diff --git a/VERSIONS_HOTLINE/64396 b/VERSIONS_HOTLINE/64396 index 2284137d7e3f9482e783f8e117d88a035993b057..71e4751cd5e91b6228a8829caa374870445486eb 100644 --- a/VERSIONS_HOTLINE/64396 +++ b/VERSIONS_HOTLINE/64396 @@ -1 +1 @@ - - ticket #64396 : Connecteur Lekiosk : Amélioration du tableau de bord \ No newline at end of file + - ticket #64396 : Ressources numériques : Amélioration de la récupération des vignettes \ No newline at end of file diff --git a/library/Class/Testing/Command.php b/library/Class/Testing/Command.php index 343a6e5ebf56a31fbed2fee8c54e552974d2c696..211a5d6c0367af98184e81a0a69f493a813f1481 100644 --- a/library/Class/Testing/Command.php +++ b/library/Class/Testing/Command.php @@ -21,11 +21,33 @@ class Class_Testing_Command extends Class_Testing_Abstract { - protected $_output, - $_return_var; + protected + $_output, + $_return_var, + $_callable; public function exec($command) { + $callable = $this->_getCallable(); + return $callable($command); + } + + + /** @category testing */ + public function setCallable($callable) { + $this->_callable = $callable; + return $this; + } + + + protected function _getCallable() { + return $this->_callable + ? $this->_callable + : [$this, '_realExec']; + } + + + protected function _realExec($command) { $output = []; $return_var = ''; $result = exec($command, $output, $return_var); @@ -35,6 +57,16 @@ class Class_Testing_Command extends Class_Testing_Abstract { } + public function execTimedScript($timeout, $script_n_args) { + $command = sprintf('timeout %s php %s/../../../scripts/%s', + $timeout, + __DIR__, + $script_n_args); + + return $this->exec($command); + } + + public function getOutput() { return $this->_output; } @@ -44,4 +76,3 @@ class Class_Testing_Command extends Class_Testing_Abstract { return $this->_return_var; } } -?> \ No newline at end of file diff --git a/library/Class/WebService/BibNumerique/RessourceNumerique.php b/library/Class/WebService/BibNumerique/RessourceNumerique.php index 2f1dca66b27841501f374b5540d8b9cb659868b1..049acee1111024364f32d17ad2a7ecbb1acb7b31 100644 --- a/library/Class/WebService/BibNumerique/RessourceNumerique.php +++ b/library/Class/WebService/BibNumerique/RessourceNumerique.php @@ -21,6 +21,8 @@ class Class_WebService_BibNumerique_RessourceNumerique { + use Trait_StaticCommand; + protected static $_logger; protected @@ -336,7 +338,7 @@ class Class_WebService_BibNumerique_RessourceNumerique { if ($album->save()) { $this->_debug('new album id: ' . $album->getId()); - Class_WebService_BibNumerique_Vignette::getInstance()->updateAlbum($album); + $this->_thumbnailAlbum($album); } if ($album->hasErrors()) @@ -348,6 +350,12 @@ class Class_WebService_BibNumerique_RessourceNumerique { } + protected function _thumbnailAlbum($album) { + $this->getCommand() + ->execTimedScript('10s', 'thumbnail_album.php ' . escapeshellarg($album->getId())); + } + + protected function getOrCreateRessourceCategorie() { $libelle = $this->getRessourceCategorieLibelle(); diff --git a/library/Trait/StaticCommand.php b/library/Trait/StaticCommand.php index 25591bca06cb07c5f20ff467733cab586cf9b940..e1f66e8f45e57aeea3aa42d7fa742636eabe6575 100644 --- a/library/Trait/StaticCommand.php +++ b/library/Trait/StaticCommand.php @@ -24,14 +24,13 @@ trait Trait_StaticCommand { protected static $_command; public static function setCommand($command) { - self::$_command = $command; + static::$_command = $command; } public static function getCommand() { - if (null !== self::$_command) - return self::$_command; + if (null !== static::$_command) + return static::$_command; return new Class_Testing_Command(); } } -?> \ No newline at end of file diff --git a/scripts/thumbnail_album.php b/scripts/thumbnail_album.php new file mode 100644 index 0000000000000000000000000000000000000000..046142f5e3a5905bf6519e986a3c6808fd2ed5e9 --- /dev/null +++ b/scripts/thumbnail_album.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright (c) 2012-2017, 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 + */ +$album_id = $argv[1]; + +require_once 'console.php'; + +if (!$album = Class_Album::find($album_id)) { + printf("Unkown album %s\n", $album_id); + exit(1); +} + +Class_WebService_BibNumerique_Vignette::getInstance()->updateAlbum($album); \ No newline at end of file diff --git a/tests/library/Class/Testing/CommandTest.php b/tests/library/Class/Testing/CommandTest.php new file mode 100644 index 0000000000000000000000000000000000000000..35adb49a5630be3b9ba48208b121bead7ab8ffb5 --- /dev/null +++ b/tests/library/Class/Testing/CommandTest.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright (c) 2012-2017, 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 + */ + + +class Class_Testing_CommandTest extends ModelTestCase { + protected + $_storm_default_to_volatile = true, + $_last_command; + + /** @test */ + public function execTimedScriptShouldContainsTimeout() { + (new Class_Testing_Command()) + ->setCallable(function($command) { $this->_last_command = $command; }) + ->execTimedScript('10s', 'thumbnail_album.php 44'); + + $this->assertContains('timeout 10s php ', $this->_last_command); + $this->assertContains('scripts/thumbnail_album.php 44', $this->_last_command); + } +} diff --git a/tests/library/Class/WebService/ArteVODFixtures.php b/tests/library/Class/WebService/ArteVODFixtures.php index c1d2b07cb43d6afdfe025a175f3492603c0c0ca4..102cfa6c572a48a9c2f7887bb9f9ae15bbda0a20 100644 --- a/tests/library/Class/WebService/ArteVODFixtures.php +++ b/tests/library/Class/WebService/ArteVODFixtures.php @@ -29,4 +29,8 @@ class ArteVODFixtures { return '[{"id":7002,"title":"Manon 20 ans","description":"<p>Envoyée en centre éducatif fermé après avoir poignardé sa mère, Manon a six mois pour faire ses preuves. Une minisérie à la puissance émotionnelle bouleversante, récompensée du Fipa d'or, avec Alba Gaïa Bellugi et Marina Foïs.</p>","themes":[],"productionYear":null,"posterUrl":"https://vod.mediatheque-numerique.com/media/59/3a/593a5d947c887.jpeg","trailerUrl":null,"url":"https://vod.mediatheque-numerique.com/films/manon-20-ans","duration":10080,"audioLanguages":[],"directors":[],"actors":[],"publicationDate":"2017-06-09","genres":["Cinéma","Série TV"],"productionCountry":null,"codes":[],"medias":[{"type":"POSTER","url":"https://vod.mediatheque-numerique.com/media/59/3a/593a5d947c887.jpeg","modificationDate":"2017-06-09T10:34:28"}],"rate":null,"comments":[],"commentsLibrary":[],"bonus":[],"availableCountries":[{"type":"Country","code":"BE"},{"type":"Country","code":"BG"},{"type":"Country","code":"CH"},{"type":"Country","code":"CZ"},{"type":"Country","code":"CY"},{"type":"Country","code":"RO"},{"type":"Country","code":"GR"},{"type":"Country","code":"SK"},{"type":"Country","code":"SI"},{"type":"Country","code":"SE"},{"type":"Country","code":"FR"},{"type":"Country","code":"DK"},{"type":"Country","code":"HU"},{"type":"Country","code":"LT"},{"type":"Country","code":"PT"},{"type":"Country","code":"TR"},{"type":"Country","code":"LI"},{"type":"Country","code":"LV"},{"type":"Country","code":"PL"},{"type":"Country","code":"LU"},{"type":"Country","code":"EE"},{"type":"Country","code":"DE"},{"type":"Country","code":"IT"},{"type":"Country","code":"ES"},{"type":"Country","code":"HR"},{"type":"Country","code":"IS"},{"type":"Country","code":"AT"},{"type":"Country","code":"MT"},{"type":"Country","code":"IE"},{"type":"Country","code":"UK"},{"type":"Country","code":"FI"},{"type":"Country","code":"NL"},{"type":"Country","code":"NO"}],"targetAudiences":[]},{"id":7009,"title":"Squadra Criminale","description":"<p>Douze meurtres. Douze histoires de crimes...<br />\r\nCapitaine à la brigade criminelle de Turin, Valeria Ferro est une enquêtrice aussi tenace que talentueuse. Elle semble posséder un sixième sens pour reconstituer le puzzle complexe de chaque affaire tout en luttant contre les fantômes de son passé. Ceux-ci resurgissent violemment dans sa vie au moment où sa mère est libérée de prison.</p>","themes":[],"productionYear":null,"posterUrl":"https://vod.mediatheque-numerique.com/media/59/3a/593a6efba55d1.jpeg","trailerUrl":"https://media.universcine.com/cd/b5/cdb57adc-2a49-11e7-b234-bdefb096dc40.mp4","url":"https://vod.mediatheque-numerique.com/films/squadra-criminale","duration":35400,"audioLanguages":[],"directors":[],"actors":[],"publicationDate":"2017-06-09","genres":["Série TV"],"productionCountry":null,"codes":[],"medias":[{"type":"POSTER","url":"https://vod.mediatheque-numerique.com/media/59/3a/593a6efba55d1.jpeg","modificationDate":"2017-06-09T11:48:43"}],"rate":null,"comments":[],"commentsLibrary":[],"bonus":[],"availableCountries":[{"type":"Country","code":"NC"},{"type":"Country","code":"BE"},{"type":"Country","code":"PF"},{"type":"Country","code":"GP"},{"type":"Country","code":"WF"},{"type":"Country","code":"GF"},{"type":"Country","code":"CH"},{"type":"Country","code":"PM"},{"type":"Country","code":"YT"},{"type":"Country","code":"FR"},{"type":"Country","code":"MF"},{"type":"Country","code":"AD"},{"type":"Country","code":"RE"},{"type":"Country","code":"MQ"},{"type":"Country","code":"MC"}],"targetAudiences":[]}]'; } + + public static function emptyPage() { + return '[]'; + } } \ No newline at end of file diff --git a/tests/library/Class/WebService/ArteVODTest.php b/tests/library/Class/WebService/ArteVODTest.php index 6990981a6a53cb66f37bb52485ba2e1c79fea209..016731cb703bbf5a386b8c170d0494b8d1384bbb 100644 --- a/tests/library/Class/WebService/ArteVODTest.php +++ b/tests/library/Class/WebService/ArteVODTest.php @@ -25,82 +25,73 @@ require_once 'ArteVODFixtures.php'; abstract class ArteVODHarverstingTestCase extends ModelTestCase { protected $_web_client; protected $_storm_default_to_volatile = true; - public function setUp() { + public function setUp() { parent::setUp(); + $this->fixture('Class_CosmoVar', ['id' => 'types_docs', 'liste' => "1:cd\r\n200:non identifié\r\n201:livres\r\n202:bd"]); - Class_AdminVar::getLoader() - ->newInstanceWithId('ARTE_VOD') - ->setValeur('1'); - Class_AdminVar::getLoader() - ->newInstanceWithId('ARTE_VOD_LOGIN') - ->setValeur('user'); - Class_AdminVar::getLoader() - ->newInstanceWithId('ARTE_VOD_KEY') - ->setValeur('pass'); - - $this->_web_client = Storm_Test_ObjectWrapper::mock(); + Class_AdminVar::set('ARTE_VOD', '1'); + Class_AdminVar::set('ARTE_VOD_LOGIN', 'user'); + Class_AdminVar::set('ARTE_VOD_KEY', 'pass'); + $this->_web_client = $this->mock(); Class_WebService_BibNumerique_ArteVOD::setDefaultHttpClient($this->_web_client); + $command = $this->mock()->whenCalled('execTimedScript')->answers(''); + Class_WebService_BibNumerique_RessourceNumerique::setCommand($command); + } + - Class_WebService_BibNumerique_Vignette::setInstance(Storm_Test_ObjectWrapper::mock() - ->whenCalled('updateAlbum') - ->answers(true)); + public function tearDown() { + Class_WebService_BibNumerique_ArteVOD::setDefaultHttpClient(null); + Class_WebService_BibNumerique_RessourceNumerique::setCommand(null); + + parent::tearDown(); } } -class ArteVODHarverstingFourFilmsInTwoPages extends ArteVODHarverstingTestCase { - protected $_category_wrapper; - protected $_album_wrapper; +class ArteVODHarverstingFourFilmsInTwoPages extends ArteVODHarverstingTestCase { public function setUp() { parent::setUp(); - $auth = ['auth' => [ 'user' => 'user', + $auth = ['auth' => ['user' => 'user', 'password' => 'pass']]; - $this->_web_client - ->whenCalled('open_url') - ->with('https://vod.mediatheque-numerique.com/api/v1/films?page_nb=1', - $auth) - ->answers(ArteVODFixtures::firstPage()) - - ->whenCalled('open_url') - ->with('https://vod.mediatheque-numerique.com/api/v1/films?page_nb=2', - $auth) - ->answers(ArteVODFixtures::secondPage()) - ->whenCalled('open_url') - ->with('https://vod.mediatheque-numerique.com/api/v1/films?page_nb=3', - $auth) - ->answers('[]') - - ->beStrict(); - $this->fixture('Class_AlbumCategorie', null); - - Class_Album::beVolatile(); + foreach(['1' => ArteVODFixtures::firstPage(), + '2' => ArteVODFixtures::secondPage(), + '3' => ArteVODFixtures::emptyPage()] + as $page => $answer) { + $this->_web_client + ->whenCalled('open_url') + ->with('https://vod.mediatheque-numerique.com/api/v1/films?page_nb=' . $page, + $auth) + ->answers($answer); + } - // should delete nothing after harvest - Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Album') - ->whenCalled('deleteBy') - ->answers(true); + $this->_web_client->beStrict(); + $this->fixture('Class_AlbumCategorie', null); - $codif_type_doc=$this->fixture('Class_CodifTypeDoc', ['id' => Class_TypeDoc::ARTEVOD, - 'famille_id' => Class_CodifTypeDoc::INCONNU, - 'bibliotheques' => '1;8', - 'annexes' => '10;12', - 'sections' => '18;19']); + // should delete nothing after harvest + $this->onLoaderOfModel('Class_Album') + ->whenCalled('deleteBy') + ->answers(true); + $codif_type_doc = $this->fixture('Class_CodifTypeDoc', + ['id' => Class_TypeDoc::ARTEVOD, + 'famille_id' => Class_CodifTypeDoc::INCONNU, + 'bibliotheques' => '1;8', + 'annexes' => '10;12', + 'sections' => '18;19']); $this->fixture('Class_TypeDoc', ['id' => Class_TypeDoc::ARTEVOD, 'codif_type_doc' => $codif_type_doc, 'label'=> 'Type doc']); - $service = new Class_WebService_BibNumerique_ArteVOD(); - $service->harvest(); + (new Class_WebService_BibNumerique_ArteVOD())->harvest(); $this->edouard = Class_Album::findFirstBy(['order' => 'id']); $this->squadra = Class_Album::findFirstBy(['titre'=> 'Squadra Criminale']); @@ -109,7 +100,7 @@ class ArteVODHarverstingFourFilmsInTwoPages extends ArteVODHarverstingTestCase { /** @test */ public function shouldHaveCreatedFourAlbums() { - $this->assertEquals(4,count(Class_Album::findAll())); + $this->assertEquals(4, count(Class_Album::findAll())); } @@ -126,9 +117,11 @@ class ArteVODHarverstingFourFilmsInTwoPages extends ArteVODHarverstingTestCase { $this->edouard->getExternalUri()); } + /** @test */ public function descriptionShouldContainsCopaindeLycee() { - $this->assertContains('Edouard est un copain de lycée et a 45 ans',$this->edouard->getDescription()); + $this->assertContains('Edouard est un copain de lycée et a 45 ans', + $this->edouard->getDescription()); } @@ -174,8 +167,8 @@ class ArteVODHarverstingFourFilmsInTwoPages extends ArteVODHarverstingTestCase { /** @test */ public function vignetteShouldHaveBeenUploaded() { - $this->assertTrue(Class_WebService_BibNumerique_Vignette::getInstance() - ->methodHasBeenCalled('updateAlbum')); + $this->assertTrue(Class_WebService_BibNumerique_RessourceNumerique::getCommand() + ->methodHasBeenCalled('execTimedScript')); } @@ -219,7 +212,7 @@ class ArteVODHarverstingFourFilmsInTwoPages extends ArteVODHarverstingTestCase { /** @test */ - public function AddingAlreadyExistingAuthorShouldNotCrashAddAuthor() { + public function addingAlreadyExistingAuthorShouldNotCrashAddAuthor() { $this->assertNotEquals(null, $this->edouard->addAuthor('Cibien, Laurent', '005')); } -} \ No newline at end of file +} diff --git a/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php b/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php index 1882b26e46deec6f25c7f19f09c0ccaa0de36e22..a058ef2d3b57e263d20e6b5d33af03e7026bc021 100644 --- a/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php +++ b/tests/scenarios/CiteDeLaMusique/CiteDeLaMusiqueTest.php @@ -264,6 +264,11 @@ class CiteDeLaMusiqueParserTest extends ModelTestCase { $this->_service = new Class_WebService_BibNumerique_CiteDeLaMusique(); Class_WebService_BibNumerique_CiteDeLaMusique::setDefaultHttpClient($this->_http_client); + Class_WebService_BibNumerique_RessourceNumerique::setCommand($this->mock() + ->whenCalled('execTimedScript') + ->answers('') + ); + $this->_service->harvest(); $this->_hommage = Class_Album::find(1); @@ -273,6 +278,7 @@ class CiteDeLaMusiqueParserTest extends ModelTestCase { public function tearDown() { CiteDeLaMusiqueFixtures::deactivate(); + Class_WebService_BibNumerique_RessourceNumerique::setCommand(null); parent::tearDown(); } @@ -347,6 +353,16 @@ class CiteDeLaMusiqueParserTest extends ModelTestCase { } + /** @test */ + public function thumbnailCommandShouldBeCalledWithTimeout() { + $command = Class_WebService_BibNumerique_RessourceNumerique::getCommand(); + $this->assertTrue($command->methodHasBeenCalled('execTimedScript')); + + $params = $command->getAttributesForLastCallOn('execTimedScript'); + $this->assertEquals('10s', $params[0]); + } + + /** @test */ public function hommageUrlOrigineShouldBeMediaDotCiteDeLaMusique() { $this->assertEquals('http://pad.philharmoniedeparis.fr/EXPLOITATION/oaiserver.ashx',