<?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 'tests/fixtures/KohaFixtures.php';

class AbonneControllerSuggestionAchatAddFormTest extends AbstractControllerTestCase {

  public function setUp() {
    parent::setUp();
    Class_CosmoVar::newInstanceWithId('types_docs', ['liste' => '']);
    $this->fixture('Class_TypeDoc', ['id' => 6 ,
                                     'label' => 'Blueray',
                                     'famille_id' => Class_CodifTypeDoc::VIDEO]);

    $this->fixture('Class_Bib', ['id' => 11,
                                 'libelle' => 'Bib de la plage']);


    Class_Profil::getCurrentProfil()
      ->setCfgModules(['abonne' => ['suggestion-achat-add' => ['help-text' => 'Entrez votre suggestion']]]);


    $this->dispatch('/opac/abonne/suggestion-achat-add', true);
  }


  /** @test */
  public function pageShouldContainsDivHelpTextWithEntrezVotreSuggestion() {
    $this->assertXPathContentContains('//div[@class="help-text"]', 'Entrez votre suggestion');
  }

  /** @test */
  public function pageTitleShouldBeSuggestionAchat() {
    $this->assertXPathContentContains('//title', 'Suggérer un achat');
  }


  /** @test */
  public function boiteShouldHaveTitleSuggestionAchat() {
    $this->assertXPathContentContains('//div[@class="boiteMilieu"]//h1', 'Suggérer un achat');
  }


  /** @test */
  public function formShouldContainsInputForTitre() {
    $this->assertXPath('//form//input[@name="titre"][@placeholder="ex: Harry Potter à l\'école des sorciers"]');
  }


  /** @test */
  public function formShouldContainsSelectForDocumentType() {
    $this->assertXPath('//form//select[@name="type_doc_id"]');
  }


  /** @test */
  public function typeDocBlueRayShouldBePresent() {
    $this->assertXPath('//form//select[@name="type_doc_id"]//option[@value="6"][@label="Blueray"]');
  }


  /** @test */
  public function rssShouldNotBePresent() {
    $this->assertNotXpath('//form//select[@name="type_doc_id"]//option[@value="9"][@label="fils rss"]');
  }


  /** @test */
  public function formShouldContainsInputForAuteur() {
    $this->assertXPath('//form//input[@name="auteur"][@placeholder="ex: Joanne Kathleen Rowling"]');
  }


  /** @test */
  public function formShouldContainsInputForDescriptionUrl() {
    $this->assertXPath('//form//input[@type="url"][@name="description_url"][@placeholder="ex: http://fr.wikipedia.org/wiki/Harry_Potter_à_l\'école_des_sorciers"]');
  }


  /** @test */
  public function formShouldContainsInputForISBN() {
    $this->assertXPath('//form//input[@name="isbn"][@placeholder="ex: 2-07-054127-4"]');
  }

  /** @test */
  public function libraryShouldBeSetByDefault() {
    $this->assertXPath('//form//select[@name="bib_id"]//option[@value="11"][@selected="selected"]');
  }

  /** @test */
  public function formShouldContainsTextAreaForCommentaire() {
    $this->assertXPath('//form//textarea[@name="commentaire"]');
  }


  /** @test */
  public function formShouldContainsSubmitButtonEnvoyer() {
    $this->assertXPath('//form//input[@type="submit"][@value="Envoyer"]');
  }
}




class AbonneControllerSuggestionAchatAddFormMultipleBibsTest extends AbstractControllerTestCase {
  protected $_storm_default_to_volatile = true;

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

    $int_bib = $this->fixture(Class_IntBib::class,
                              ['id' => 21,
                               'nom_court' => 'plage']);

    $this->fixture(Class_Bib::class,
                   ['id' => 21,
                    'libelle' => 'Bib de la plage',
                    'int_bib' => $int_bib]);

    $this->fixture(Class_Bib::class,
                   ['id' => 12,
                    'libelle' => 'Bib de la plage 2']);

    $user = $this->fixture(Class_Users::class,
                           ['id' => 3,
                            'login' => 'test',
                            'password' => 'test',
                            'id_site' => 12]);

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

    $this->dispatch('/opac/abonne/suggestion-achat-add');
  }


  /** @test */
  public function formShouldContainsSelectForLibrary() {
    $this->assertXPath('//form//select[@name="bib_id"]');
  }


  /** @test */
  public function librarySelectShouldContainBibDeLaPlage() {
    $this->assertXPath('//form//select[@name="bib_id"]//option[@value="21"][@label="Bib de la plage"]/following-sibling::option[@value="12"][@label="Bib de la plage 2"]');
  }


  /** @test */
  public function noLibraryShouldHaveBeenSelectedByDefault() {
    $this->assertXPath('//form//select[@name="bib_id"]//option[1][@value="0"]');
  }
}




class AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaNotCommunityTest extends AbstractControllerTestCase {
  public function setUp() {
    parent::setUp();
    $sigb_plage = $this->fixture('Class_IntBib',
                                 [
                                  'id' => 3,
                                  'comm_params' => ['url_serveur' => 'http://plage.com/cgi-bin/koha/ilsdi.pl'],
                                  'comm_sigb' => Class_IntBib::COM_KOHA_LEGACY
                                 ]);

    $this->fixture('Class_Bib', ['id' => 12,
                                 'libelle' => 'Bib de la plage 2',
                                 'int_bib' => $sigb_plage]);

    $user = $this->fixture('Class_Users', [
                                           'id' => 3,
                                           'login' => 'test',
                                           'password' => 'test',
                                           'id_site' => 12,
                                           'date_maj' => '',
                                           'int_bib' => $sigb_plage,
                                           ]);

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

    $this->dispatch('/opac/abonne/suggestion-achat-add', true);
  }


  /** @test */
  public function formShouldContainsTextAreaForCommentaire() {
    $this->assertXPath('//form//textarea[@name="commentaire"]');
  }


  /** @test */
  public function pageShouldNotContainsDivHelpText() {
    $this->assertNotXPath('//div[@class="help-text"]');
  }

}




abstract class AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase extends AbstractControllerTestCase {

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

    $sigb_plage =
      $this->fixture(Class_IntBib::class,
                     ['id' => 3,
                      'comm_params' => ['url_serveur' => 'http://plage.com/cgi-bin/koha/ilsdi.pl',
                                        'api_user' => 'koha_admin',
                                        'api_pass' => 'koha_password'],
                      'comm_sigb' => Class_IntBib::COM_KOHA
                     ]);

    $this->fixture(Class_Bib::class,
                   ['id' => 11,
                    'libelle' => 'Bib de la plage',
                    'int_bib' => $sigb_plage]);

    $this->fixture(Class_Bib::class,
                   ['id' => 12,
                    'libelle' => 'Bib de la plage 2',
                    'int_bib' => $sigb_plage]);

    $this->fixture(Class_Bib::class,
                   ['id' => 14,
                    'libelle' => 'Bib de la montagne']);

    $istres =
      $this->fixture(Class_CodifAnnexe::class,
                     ['id' => 15,
                      'libelle' => 'Istres',
                      'id_origine' => 'IST']);

    $borrower = new Class_WebService_SIGB_Emprunteur('2341', 'test');
    $borrower->setLibraryCode('IST');

    $user = $this->fixture(Class_Users::class,
                           ['id' => 3,
                            'login' => 'test',
                            'password' => 'test',
                            'id_site' => 12,
                            'id_sigb' => 'azerty',
                            'int_bib' => $sigb_plage,
                            'fiche_sigb' => ['type_comm' => 0,
                                             'fiche' => $borrower]]);

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

    $this->mock_web_client = $this->mock();
    $sigb_comm = Class_IntBib::find(3)->getSIGBComm();
    $sigb_comm->setWebClient($this->mock_web_client);
  }


  public function tearDown() {
    Class_IntBib::find(3)->getSIGBComm()->setWebClient(null);
    parent::tearDown();
  }
}




class AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTest
  extends AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase {

  public function setUp() {
    parent::setup();
    $this->dispatch('/opac/abonne/suggestion-achat-add');
  }


  /** @test */
  public function formShouldContainsTextAreaForNote() {
    $this->assertXPath('//form//textarea[@name="Note"]');
  }


  /** @test */
  public function formShouldContainsInputForTitle() {
    $this->assertXPath('//form//input[@name="Title"][@placeholder="ex: Harry Potter à l\'école des sorciers"]');
  }


  /** @test */
  public function formShouldContainsInputForAuthor() {
    $this->assertXPath('//form//input[@name="Author"][@placeholder="ex: Joanne Kathleen Rowling"]');
  }


  /** @test */
  public function formShouldContainsInputForIsbn() {
    $this->assertXPath('//form//input[@name="Isbn"][@placeholder="ex: 2-07-054127-4"]');
  }


  /** @test */
  public function formShouldContainsInputForPublicationYear() {
    $this->assertXPath('//form//input[@name="PublicationYear"][@placeholder="2015"]');
  }


  /** @test */
  public function formShouldContainsBranchNameIstres() {
    $this->assertXPath('//form//input[@name="BranchName"][@value="Istres"]');
  }


  /** @test */
  public function formShouldContainsSelectForDocType() {
    $this->assertXPathContentContains('//form//select[@name="DocType"]//option[@value="3"]',
                                      'Disques');
  }


  /** @test */
  public function docTypeForDiscsShouldBeAtFirstPlace() {
    $this->assertXPathContentContains('//form//select[@name="DocType"]//option[1]', 'Disques');
  }


  /** @test */
  public function defaultDocTypeShouldBeBook() {
    $this->assertXPathContentContains('//form//select[@name="DocType"]//option[@value="1"][@selected]',
                                      'Livres');
  }
}




class AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaCommunityPostTest extends AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase {
  public function setUp() {
    parent::setUp();

    $this->mock_web_client
      ->whenCalled('postRawData')
      ->with('http://plage.com/api/v1/suggestions',
             '{"suggested_by":"2341","title":"Harry Potter","item_type":"Livres","author":"J.K.Rowling","isbn":"2-07-0541 27_4","note":"Je veux le lire","publication_year":"2014","library_id":"IST"}',
             Class_WebService_SIGB_Koha_CommunityService::JSON_ENCODED,
             ['auth' => ['user' => 'koha_admin',
                         'password' => 'koha_password']])
      ->answers(KohaCommunityFixtures::suggestionSuccess())
      ->beStrict();

    $sigb_comm = Class_IntBib::find(3)->getSIGBComm();
    $sigb_comm->setWebClient($this->mock_web_client);

    $this->postDispatch('/opac/abonne/suggestion-achat-add',
                        ['Title' => 'Harry Potter',
                         'Author' => 'J.K.Rowling',
                         'Isbn' => '2-07-0541 27_4',
                         'Note' => 'Je veux le lire',
                         'PublicationYear' => '2014',
                         'BranchCode' => 'IST',
                         'DocType' => '1',
                         'submit' => 'Envoyer']);
  }


  /** @test */
  public function dataShouldHaveBeenPosted() {
    $this->assertTrue($this->mock_web_client->methodHasBeenCalled('postRawData'));
  }


  /** @test */
  public function dataShouldBeJsonEncoded() {
    $datas = json_decode($this->mock_web_client->getAttributesForLastCallOn('postRawData')[1],
                         true);
    $this->assertEquals(['title' => 'Harry Potter',
                         'item_type' => 'Livres',
                         'author' => 'J.K.Rowling',
                         'isbn' => '2-07-0541 27_4',
                         'note' => 'Je veux le lire',
                         'publication_year' => '2014',
                         'suggested_by' => '2341',
                         'library_id' => 'IST'],
                        $datas);
  }
}




class AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaPostWrongDataTest
  extends AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase {

  public function setUp() {
    parent::setUp();
    $this->postDispatch('/opac/abonne/suggestion-achat-add',
                        ['Title' => '',
                         'Author' => '',
                         'Isbn' => '',
                         'Note' => '',
                         'PublicationYear' => 'toto',
                         'submit' => 'Envoyer']);
  }


  /** @test */
  public function inputTitleShouldHaveErrorRequiredValue() {
    $this->assertXPathContentContains('//input[@id="Title"]/following-sibling::ul/li',
                                      'Une valeur est requise');
  }


  /** @test */
  public function inputAuthorShouldHaveErrorRequiredValue() {
    $this->assertXPathContentContains('//input[@id="Author"]/following-sibling::ul/li',
                                      'Une valeur est requise');
  }


  /** @test */
  public function inputPublicationYearShouldHaveErrorBeInt() {
    $this->assertXPathContentContains('//input[@id="PublicationYear"]/following-sibling::ul/li',
                                      "'toto' n'est pas un nombre entier");
  }
}



abstract class AbonneControllerSuggestionAchatAddPostTestCase extends AbstractControllerTestCase {
  protected
    $_suggestion,
    $_storm_default_to_volatile = true,
    $_mail;

  protected function _loginHook($account) {
    $account->username     = 'Arnaud';
    $account->ID_USER      = 666;
  }


  public function setUp() {
    parent::setUp();
    Class_CosmoVar::newInstanceWithId('types_docs', ['liste' => '']);
    $codif_type_doc=$this->fixture('Class_CodifTypeDoc', ['id' => 102,
                                                          'famille_id' => Class_CodifTypeDoc::LIVRE,
                                                          'bibliotheques' => '2;3',
                                                          'annexes' => '4;8',
                                                          'sections' => '9;10']);

    $this->fixture('Class_TypeDoc', ['id' => Class_TypeDoc::LIVRE,
                                     'codif_type_doc' =>  $codif_type_doc,
                                     'label'=> 'Livres Numériques']);

    Storm_Test_ObjectWrapper::onLoaderOfModel('Class_SuggestionAchat')
      ->whenCalled('save')
      ->willDo(
               function($suggestion){
                 $this->_suggestion = $suggestion->setId(66);
               });
  }
}




class AbonneControllerSuggestionAchatAddPostValidDataTest extends AbonneControllerSuggestionAchatAddPostTestCase {
  public function setUp() {
    parent::setUp();

    $this->fixture('Class_Bib', ['id' => 11,
                                 'libelle' => 'Bib de la plage',
                                 'mail' => 'albert@jean.fr',
                                 'mail_suggestions' => '']);

    $mock_transport = new MockMailTransport();
    Zend_Mail::setDefaultTransport($mock_transport);

    $this->postDispatch('/opac/abonne/suggestion-achat-add',
                        ['titre' => 'Harry Potter',
                         'auteur' => 'J.K.Rowling',
                         'type_doc_id' => Class_TypeDoc::LIVRE,
                         'description_url' => 'http://harrypotter.fr',
                         'isbn' => '2-07-0541 27_4',
                         'bib_id' => '11',
                         'commentaire' => 'Je veux le lire',
                         'submit' => 'Envoyer']);

    $this->_mail = $mock_transport->sent_mail;
  }


  /** @test */
  public function newSuggestionShouldHaveTitreHarryPotter() {
    $this->assertEquals('Harry Potter', $this->_suggestion->getTitre());
  }


  /** @test */
  public function newSuggestionShouldHaveAuteurJKRowling() {
    $this->assertEquals('J.K.Rowling', $this->_suggestion->getAuteur());
  }


  /** @test */
  public function newSuggetionShouldHaveDescriptionUrlHarryPotterDotFr() {
    $this->assertEquals('http://harrypotter.fr', $this->_suggestion->getDescriptionUrl());
  }


  /** @test */
  public function newSuggestionsShouldHaveIsbn2070541274() {
    $this->assertEquals('2070541274', $this->_suggestion->getIsbn());
  }


  /** @test */
  public function newSuggestionsShouldHaveDocumentType2() {
    $this->assertEquals('Livres Numériques', $this->_suggestion->getTypeDoc()->getLibelle());
  }


  /** @test */
  public function shouldNotHaveSubmitAttribute() {
    $this->assertNotContains('submit', array_keys($this->_suggestion->toArray()));
  }


  /** @test */
  public function newSuggestionShouldHaveCommentaireJeVeuxLeLire() {
    $this->assertEquals('Je veux le lire', $this->_suggestion->getCommentaire());
  }


  /** @test */
  public function newSuggestionShouldBelongsToArnaud() {
    $this->assertEquals('Arnaud', $this->_suggestion->getUser()->getLogin());
  }


  /** @test */
  public function newSuggetionShouldDateCreationShouldBeToday() {
    $this->assertEquals(date('Y-m-d'), $this->_suggestion->getDateCreation());
  }


  /** @test */
  public function responseShouldRedirectToSuggestionAchatId66() {
    $this->assertRedirectTo(Class_Url::absolute('/abonne/suggestion-achat'));
  }


  /** @test */
  public function sentMailSubjectShouldBeSuggestionAchatHarryPotter() {
    $this->assertEquals('Suggestion d\'achat: Harry Potter', $this->_mail->getSubject());
  }


  /** @test */
  public function fromShouldBeNoReplyAtLocalhost() {
    $this->assertEquals('noreply@localhost', $this->_mail->getFrom());
  }


  /** @test */
  public function toShouldBeJeanJeanFr() {
    $this->assertEquals('albert@jean.fr', $this->_mail->getRecipients()[0]);
  }


  /** @test */
  public function saveShouldBeNotified() {
    $this->assertFlashMessengerContentContains('Suggestion d\'achat enregistrée');
  }
}




class AbonneControllerSuggestionAchatAddPostWithMailSuggestions extends AbonneControllerSuggestionAchatAddPostTestCase {
  public function setUp() {
    parent::setUp();

    $this->fixture('Class_Bib', ['id' => 11,
                                 'libelle' => 'Bib de la plage',
                                 'mail' => 'jean@jean.fr',
                                 'mail_suggestions' => 'jean@jean.fr']);

    $mock_transport = new MockMailTransport();
    Zend_Mail::setDefaultTransport($mock_transport);

    $this->postDispatch('/opac/abonne/suggestion-achat-add',
                        ['titre' => 'Harry Potter',
                         'auteur' => 'J.K.Rowling',
                         'type_doc_id' => Class_TypeDoc::LIVRE,
                         'description_url' => 'http://harrypotter.fr',
                         'isbn' => '2-07-0541 27_4',
                         'bib_id' => '11',
                         'commentaire' => 'Je veux le lire',
                         'submit' => 'Envoyer']);

    $this->_mail = $mock_transport->sent_mail;
  }


  /** @test */
  public function toShouldBeJeanJeanFr() {
    $this->assertEquals('jean@jean.fr', $this->_mail->getRecipients()[0]);
  }
}




class AbonneControllerSuggestionAchatAddPostValidDataButNoMailSentTest extends AbstractControllerTestCase {
  protected $_storm_default_to_volatile = true;
  protected $_suggestion;
  protected $_mail;


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

    Class_Users::getIdentity()->setMail('');
    Class_Profil::getPortail()->setMailSite('');
    Class_Profil::getCurrentProfil()->setMailSite('');

    $mock_transport = new MockMailTransport();
    Zend_Mail::setDefaultTransport($mock_transport);
    $mock_transport->onSendDo(function() {throw new Zend_Mail_Exception('some error');});

    $this->postDispatch('/opac/abonne/suggestion-achat-add',
                        ['titre' => 'Harry Potter',
                         'description_url' => '',
                         'type_doc_id' => 2,
                         'isbn' => '',
                         'commentaire' => '',
                         'submit' => 'Envoyer']);
  }


  /** @test */
  public function notificationShouldContainsAucunCourrielEnvoye() {
    $this->assertFlashMessengerContentContains('Aucun courriel envoyé, erreur: some error');
  }


  /** @test */
  public function newSuggestionShouldHaveTitreHarryPotter() {
    $this->assertNotNull(Class_SuggestionAchat::findFirstBy(['titre' => 'Harry Potter']));
  }
}




class AbonneControllerSuggestionAchatAddPostWrongDataTest extends AbstractControllerTestCase {
  protected $_storm_default_to_volatile = true;

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

    Class_Profil::getCurrentProfil()
      ->setCfgModules(['index' => ['formulairecontact' => ['bib_selector' => 1]]]);

    $this->fixture('Class_Bib',
                   ['id' => 2,
                    'libelle' => 'My Bib',
                    'mail' => 'my_bib@afi-sa.fr']);

    Class_SuggestionAchat::beVolatile();

    $this->postDispatch('/opac/abonne/suggestion-achat-add',
                        ['titre' => '',
                         'auteur' => '',
                         'bib_id' => '0',
                         'description_url' => 'h p',
                         'isbn' => '207',
                         'commentaire' => '']);
  }


  /** @test */
  public function errorForTitreAndCommentaireShouldBeTitreOuCommentaireRequis() {
    $this->assertXPathContentContains('//li', 'Titre ou commentaire requis');
  }


  /** @test */
  public function errorForDescriptionUrlShouldBeURLInvalide() {
    $this->assertXPathContentContains('//li', '\'h p\' n\'est pas une URL valide');
  }


  /** @test */
  public function errorForIsbnShouldBeFormatIncorrect() {
    $this->assertXPathContentContains('//li', '\'207\' n\'est pas un ISBN valide');
  }


  /** @test */
  public function errorForBibSelectorShouldBePresent() {
    $this->assertXPathContentContains('//li', 'Veuillez sélectionner une bibliothèque');
  }
}




class AbonneControllerSuggestionAchatAddDataWithEmptyFieldsNotRequiredTest extends AbstractControllerTestCase {
  protected $_storm_default_to_volatile = true;

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

    Storm_Test_ObjectWrapper::onLoaderOfModel('Class_SuggestionAchat')
      ->whenCalled('save')
      ->answers(true);

    $this->postDispatch('/opac/abonne/suggestion-achat-add',
                        ['titre' => 'Millenium',
                         'auteur' => 'Stieg Larsson',
                         'type_doc_id' => 2,
                         'description_url' => '',
                         'isbn' => '',
                         'commentaire' => ''],
                        true);
  }


  /** @test */
  public function responseShouldBeARedirect() {
    $this->assertRedirect();
  }
}




class AbonneControllerSuggestionAchatAddWithIdTest extends AbstractControllerTestCase {
  public function setUp() {
    parent::setUp();
    Class_SuggestionAchat::newInstanceWithId(66);
    $this->dispatch('/opac/abonne/suggestion-achat-add/id/66', true);
  }


  /** @test */
  public function pageShouldDisplaySuggestionPriseEnCompte() {
    $this->assertXPathContentContains('//p', 'Votre suggestion d\'achat');
  }


  /** @test **/
  public function pageShouldContainsALinkToSuggestionAchat() {
    $this->assertXPath('//a[contains(@href, "/abonne/suggestion-achat")]',$this->_response->getBody());
  }

}



class AbonneControllerSuggestionAchatWithOutSuggestionTest extends AbstractControllerTestCase {
  protected $_storm_default_to_volatile = true;

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

    $this->dispatch('/opac/abonne/suggestion-achat', true);
  }


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


  /** @test **/
  public function pageShouldDisplayPasDeSuggestion() {
    $this->assertXpathContentContains('//div/span', 'Vous n\'avez pas encore fait de suggestion.',$this->_response->getBody());
  }

}



class AbonneControllerSuggestionAchatWithOneSuggestionTest extends AbstractControllerTestCase {
  protected $_storm_default_to_volatile = true;

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

    $user = $this->fixture('Class_Users',
                           ['id' => 1,
                            'login' => 'Tom',
                            'password' => 'pwd']);

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


    $suggestion = $this->fixture('Class_SuggestionAchat',
                                 ['id' => 1,
                                  'commentaire' => 'New edition is available.',
                                  'description_url' => '',
                                  'isbn' => '',
                                  'type_doc_id' => Class_CodifTypeDoc::VIDEO]);

    $user->setSuggestionAchat([$suggestion])->save();

    $this->dispatch('/opac/abonne/suggestion-achat', true);
  }


  /** @test */
  public function loggedUserShouldHaveOneSuggestion() {
    $this->assertXPathContentContains('//table[@class="tablesorter"]/thead/th', 'Commentaire');
  }


  /** @test */
  public function suggestionShouldHaveTypeDocDVD() {
    $this->assertXPathContentContains('//table/tbody/tr/td', 'DVD');
  }
}




class AbonneControllerSuggestionAchatWithOneKohaSuggestionTest
  extends AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase {

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

    $logger = $this->mock()
                   ->whenCalled('log')->answers(true)

                   ->whenCalled('logError')
                   ->willDo(
                            function($url, $message) {
                              throw new RuntimeException($url . ' :: ' . $message);
                            });

    Class_WebService_SIGB_AbstractService::setLogger($logger);

    $this->mock_web_client
      ->whenCalled('open_url')
      ->with('http://plage.com/api/v1/suggestions?q=' . urlencode('{"suggested_by":"2341"}'),
             ['auth' => ['user' => 'koha_admin', 'password' => 'koha_password']])
      ->answers('[{
      "date" : "2014-04-01T16:08:36+02:00",
      "status" : "ASKED",
      "suggestion_id" : "6197",
      "accepted_date" : "",
      "managed_by" : "",
      "isbn" : "9782814101425 ",
      "library_id" : "IST",
      "copyright_date" : "0",
      "reason" : null,
      "total" : "",
      "price" : "",
      "title" : "En piste ! : Créations en couture pour petits et grands Enfant",
      "publication_year" : "2012",
      "itemtype" : "",
      "place" : "",
      "author" : "Laëtitia Gheno",
      "suggested_date" : "2013-11-14",
      "currency" : "",
      "biblio_id" : "",
      "suggested_by" : "2341",
      "rejected_date" : null,
      "rejected_by" : null,
      "quantity" : "0",
      "note" : "Je veux le lire",
      "patron_reason" : "Je veux le lire",
      "volumedesc" : null,
      "mailoverseeing" : "0",
      "managedby" : ""}]')
      ->beStrict();

    $this->fixture('Class_CodifAnnexe',
                   ['id' => 15,
                    'libelle' => 'Istres',
                    'id_origine' => 'IST']);


    $this->dispatch('/opac/abonne/suggestion-achat', true);
  }


  public function tearDown() {
    Class_WebService_SIGB_AbstractService::setLogger(null);
    parent::tearDown();
  }


  /** @test */
  public function titleShouldBePresent() {
    $this->assertXPathContentContains('//td', 'En piste ! : Créations en couture pour petits et grands Enfant');
  }


  /** @test */
  public function authorShouldBePrensent() {
    $this->assertXPathContentContains('//td', 'Laëtitia Gheno');
  }


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


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


  /** @test */
  public function suggestDateShouldBePresent() {
    $this->assertXPathContentContains('//td', '2013-11-14');
  }


  /** @test */
  public function noteShouldBePresent() {
    $this->assertXPathContentContains('//td', 'Je veux le lire');
  }


  /** @test */
  public function statusShouldBePresent() {
    $this->assertXPathContentContains('//td', 'En attente');
  }
}




class AbonneControllerSuggestionAchatWithKohaErrorTest
  extends AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase {

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

    $logger = $this->mock()
                   ->whenCalled('log')->answers(true)

                   ->whenCalled('logError')
                   ->willDo(
                            function($url, $message) {
                              throw new RuntimeException($url . ' :: ' . $message);
                            });

    Class_WebService_SIGB_AbstractService::setLogger($logger);

    $this->mock_web_client
      ->whenCalled('open_url')
      ->with('http://plage.com/api/v1/suggestions?q=' . urlencode('{"suggested_by":"2341"}'),
             ['auth' => ['user' => 'koha_admin', 'password' => 'koha_password']])
      ->answers('{"errors":"Forbidden. 178.16.171.35 is not allowed to use this service. Are you sure configuration variable \'authorizedips\' is correctly configured?"}');

    $this->fixture(Class_CodifAnnexe::class,
                   ['id' => 15,
                    'libelle' => 'Istres',
                    'id_origine' => 'IST']);

    $this->dispatch('/opac/abonne/suggestion-achat');
  }


  public function tearDown() {
    Class_WebService_SIGB_AbstractService::setLogger(null);
    parent::tearDown();
  }


  /** @test */
  public function shouldNotDisplaySuggestionsList() {
    $this->assertNotXPath('//div[@class="suggestion-achat-liste"]//table');
  }


  /** @test */
  public function shouldDisplayWebserviceError() {
    $this->assertXPathContentContains('//div',
                                      'Erreurs du webservice');
  }
}




class ModulesControllerAbonneSuggestionAchatTest extends Admin_AbstractControllerTestCase {
  public function setUp() {
    parent::setUp();


    Class_Profil::getCurrentProfil()
      ->setCfgModules(['abonne' => ['suggestion-achat-add' => ['help-text' => 'Entrez votre suggestion']]]);

    $this->dispatch('/admin/modules/abonne?id_profil=2&action1=suggestion-achat-add&type_module=abonne&config=site', true);
  }

  /** @test */
  public function titleShouldBeProperty() {
    $this->assertXPathContentContains('//h1', 'Propriétés du module : Suggestions d\'achat');
  }


  /** @test */
  public function textareHelpTextShouldContainsEntrezVotreSuggestion() {
    $this->assertXPathContentContains('//textarea[@name="help-text"]',
                                      'Entrez votre suggestion');
  }


  /** @test */
  public function textareHelpTextShouldBeCkeditor() {
    $this->assertXPathContentContains('//script',
                                      'CKEDITOR.replace(\'cke-help-text\'');
  }
}




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

    $this->fixture('Class_Bib', ['id' => 11, 'libelle' => 'Test']);
    $this->fixture('Class_Bib', ['id' => 12, 'libelle' => 'Mer']);
    $this->fixture('Class_Bib', ['id' => 13, 'libelle' => 'Agence']);
    $this->fixture('Class_Bib', ['id' => 14, 'libelle' => 'Plage']);

    $this->dispatch('abonne/suggestion-achat-add', true);
  }

  /** @test */
  public function BibSelectShouldBeAgence() {
    $this->assertXPath('//form//select[@name="bib_id"]//option[2][@value="13"]');
  }

  /** @test */
  public function BibSelectShouldBeMer() {
    $this->assertXPath('//form//select[@name="bib_id"]//option[3][@value="12"]');
  }

  /** @test */
  public function BibSelectShouldBePlage() {
    $this->assertXPath('//form//select[@name="bib_id"]//option[4][@value="14"]');
  }

  /** @test */
  public function BibSelectShouldBeTest() {
    $this->assertXPath('//form//select[@name="bib_id"]//option[5][@value="11"]');
  }
}


class AbonneControllerSuggestionAchatInactiveTest
  extends AbstractControllerTestCase {

  protected $_storm_default_to_volatile = true;

  public function setUp() {
    parent::setUp();
    $this->fixture('Class_AdminVar', ['id' => 'DISABLE_SUGGESTIONS',
                                      'valeur' => '1']);
  }


  public function provider() {
    return [['/abonne/suggestion-achat'],
            ['/abonne/suggestion-achat-add'],
            ['/abonne/suggestion-achat-ok']];
  }


  /**
   * @test
   * @dataProvider provider
   **/
  public function shouldContainsDisabledMessage($url) {
    $this->dispatch($url, true);
    $this->assertXPathContentContains('//div',
                                      'les suggestions d\'achats ne sont pas possibles pour le moment.',
                                      $this->_response->getBody());
  }
}




class AbonneControllerSuggestionAchatAddPostAndRecordsFoundTest extends AbonneControllerSuggestionAchatAddPostTestCase {
  protected $_storm_default_to_volatile = true;

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

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

    $mock_transport = new MockMailTransport();
    Zend_Mail::setDefaultTransport($mock_transport);

    $search_result = $this
      ->mock()->beStrict()
      ->whenCalled('fetchRecords')
      ->answers([$this->fixture('Class_Notice',
                                ['id' => 1,
                                 'titre_principal' => 'Trolls de Troy'])]);

    $search_engine = $this
      ->mock()
      ->whenCalled('lancerRecherche')
      ->answers($search_result);

    Class_MoteurRecherche::setInstance($search_engine);

    $this->postDispatch('/opac/abonne/suggestion-achat-add',
                        ['DocType' => Class_TypeDoc::LIVRE,
                         'Site' => '12',
                         'titre' => 'Trolls de Troy']);
  }


  /** @test */
  public function recordsListShouldContainsTrollsDeTroy() {
    $this->assertXPathContentContains('//div', 'Trolls de Troy', $this->_response->getBody());
  }
}




class AbonneControllerSuggestionAchatAddPostWithValidateSuggestionTest extends AbonneControllerSuggestionAchatAddPostTestCase {

  protected $_storm_default_to_volatile = true;


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

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

    $mock_transport = new MockMailTransport();
    Zend_Mail::setDefaultTransport($mock_transport);

    $search_result = $this
      ->mock()->beStrict()
      ->whenCalled('fetchRecords')
      ->answers([$this->fixture('Class_Notice',
                                ['id' => 1,
                                 'titre_principal' => 'Le mystère de la patate. Une enquête de l\'inspecteur Lapou'])]);

    $search_engine = $this
      ->mock()
      ->whenCalled('lancerRecherche')
      ->answers($search_result);

    Class_MoteurRecherche::setInstance($search_engine);

    $this->postDispatch('/opac/abonne/suggestion-achat-add/validate_suggestion/1',
                        ['titre' => 'Le mystère de la patate',
                         'auteur' => 'Bénédicte Guettier',
                         'type_doc_id' => Class_TypeDoc::LIVRE,
                         'commentaire' => 'Une enquête de l\'inspecteur Lapou']);
  }


  /** @test */
  public function responseShouldRedirect() {
    $this->assertRedirect();
  }


  /** @test */
  public function assertFlashMessengerShouldContainsSuggestionAdded() {
    $this->assertFlashMessengerContentContains('Suggestion d\'achat enregistrée');
  }
}