diff --git a/FEATURES/125727 b/FEATURES/125727 new file mode 100644 index 0000000000000000000000000000000000000000..2443168d39bcb49d5a9dce81f57b67bdbcfbce75 --- /dev/null +++ b/FEATURES/125727 @@ -0,0 +1,10 @@ + '125727' => + ['Label' => $this->_('Facette nouveauté en résultat de recherche'), + 'Desc' => $this->_('Ajout de la possibilité d\'afficher une facette "Nouveauté" oui/non basée sur la date de nouveauté la plus élevée parmis tous les exemplaires'), + 'Image' => '', + 'Video' => '', + 'Category' => $this->_('Recherche'), + 'Right' => function($feature_description, $user) {return true;}, + 'Wiki' => 'http://wiki.bokeh-library-portal.org/index.php?title=Facette_%27Nouveaut%C3%A9%27', + 'Test' => '', + 'Date' => '2021-01-14'], \ No newline at end of file diff --git a/VERSIONS_WIP/125727 b/VERSIONS_WIP/125727 new file mode 100644 index 0000000000000000000000000000000000000000..d3e051728ca258acc59923c01351521fcb5211ef --- /dev/null +++ b/VERSIONS_WIP/125727 @@ -0,0 +1 @@ + - ticket #125727 : Résultat de recherche : Ajout de la possibilité d'afficher une facette "Nouveauté" oui/non basée sur la date de nouveauté la plus élevée parmis tous les exemplaires \ No newline at end of file diff --git a/cosmogramme/tests/php/classes/KohaPeriodiquesTest.php b/cosmogramme/tests/php/classes/KohaPeriodiquesTest.php index aa9e530cf645174aef5287228255c20b5f92f3de..6a0917953eeb48d8dadd20591485c828708d7ac5 100644 --- a/cosmogramme/tests/php/classes/KohaPeriodiquesTest.php +++ b/cosmogramme/tests/php/classes/KohaPeriodiquesTest.php @@ -659,7 +659,7 @@ class KohaPeriodiquesMatriculeAngesTest extends KohaPeriodiquesWithArticlesTestC $title->updateFacetsFromExemplaires(); - $this->assertEquals('D800 Lfre Tper_title B1 YCHYJR', + $this->assertEquals('D800 Lfre Tper_title B1 YCHYJR HNRNR0001', $title->getFacettes()); } diff --git a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php index eb8932f3b92d7de859959eaab17011ccd5a0d44f..171fcb29a5cc0a205e29c67aed00fc07aba6af9c 100644 --- a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php +++ b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php @@ -233,7 +233,7 @@ class KohaRecordIntegrationFacetPresseTest extends KohaRecordIntegrationTestCase /** @test */ public function facettesShouldContainsT2AndHANNE0001AndHMOIS0001AndJOUR0001() { - $this->assertEquals('HANNE0001 HMOIS0001 HJOUR0001 Lfre T2 B1 YMEDSTMAR', + $this->assertEquals('HANNE0001 HMOIS0001 HJOUR0001 Lfre T2 B1 YMEDSTMAR HNRNR0001', Class_Notice::find(1) ->updateFacetsFromExemplaires() ->getFacettes()); @@ -242,7 +242,7 @@ class KohaRecordIntegrationFacetPresseTest extends KohaRecordIntegrationTestCase /** @test */ public function facettesForRecord25ShouldContainsT2AndHANNE0001AndHMOIS0001() { - $this->assertEquals('HANNE0001 HMOIS0007 HJOUR0006 Lfre T2 B1 YMEDSTMAR', + $this->assertEquals('HANNE0001 HMOIS0007 HJOUR0006 Lfre T2 B1 YMEDSTMAR HNRNR0001', Class_Notice::find(25) ->updateFacetsFromExemplaires() ->getFacettes()); diff --git a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php index 7eb4afa2c5345eb4ed2c330b1c1e2c167f8f11d5..9dc927120c59e4c3df7bed2afc483e2e60ab4eae 100644 --- a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php +++ b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php @@ -1239,7 +1239,7 @@ class NoticeIntegrationArchivesAlsaceTest extends NoticeIntegrationTestCase { /** @test */ public function facettesWithExemplairesShouldContainsM1AndM2AndD1() { - $this->assertEquals('D94438 A1 M1 M2 Lfre T1 B1 YBibliothèque des Dominicains', + $this->assertEquals('D94438 A1 M1 M2 Lfre T1 B1 YBibliothèque des Dominicains HNRNR0001', Class_Notice::find(1)->updateFacetsFromExemplaires()->getFacettes()); } } diff --git a/library/Class/Catalogue.php b/library/Class/Catalogue.php index c24c70ddb03ee2cb89cbc65119ab72f82a1c44a1..d3ee2453d3f0dda5cda05ec3eec0f8e27e89b0fd 100644 --- a/library/Class/Catalogue.php +++ b/library/Class/Catalogue.php @@ -1142,7 +1142,7 @@ class Class_Catalogue extends Storm_Model_Abstract { public function getThesaurusForId($thesaurus) { - $startWith = substr($thesaurus->getIdThesaurus(), 0, Class_Notice_Facette::NB_CHAR_THESAURUS); + $startWith = substr($thesaurus->getIdThesaurus(), 0, Class_CodifThesaurus::ID_KEY_LENGTH); $ids=''; $thesaurus_ids = explode(';',$this->getThesaurus()); diff --git a/library/Class/CodifThesaurus.php b/library/Class/CodifThesaurus.php index 96b7cf158636b228fe908a303cffa07d42efc0a9..309d09f80ea7701e0454467272026c4ce34d0773 100644 --- a/library/Class/CodifThesaurus.php +++ b/library/Class/CodifThesaurus.php @@ -69,6 +69,23 @@ class CodifThesaurusLoader extends Storm_Model_Loader { } + public function ensureRecordNovelty() { + $this->recordNoveltyFor(true); + $this->recordNoveltyFor(false); + } + + + /** @param $flag boolean */ + public function recordNoveltyFor($flag) { + $attributes = ((bool) $flag) + ? ['Id' => 1, 'Libelle' => $this->_('Oui')] + : ['Id' => 2, 'Libelle' => $this->_('Non')]; + + return $this->ensureForModelUnderRoot(new Class_Entity($attributes), + $this->_fixed['RecordNovelty']); + } + + public function ensureForModelUnderRoot($model, $definition) { return ($root = Class_CodifThesaurus::findRootOfId($definition->getId(), $definition->getCode(), @@ -213,7 +230,7 @@ class CodifThesaurusLoader extends Storm_Model_Loader { public function findParent($id_thesaurus) { - $parent_str=substr($id_thesaurus,0,strlen($id_thesaurus)-(4-strlen($id_thesaurus)%4)); + $parent_str = substr($id_thesaurus, 0, strlen($id_thesaurus) - (4 - strlen($id_thesaurus) % 4)); if (!$parent_str) return null; @@ -298,7 +315,7 @@ class CodifThesaurusLoader extends Storm_Model_Loader { public function getIndices($pere, $all = false ) { - if(Class_CodifThesaurus::CODE_ROOT != $pere) { + if (Class_CodifThesaurus::CODE_ROOT != $pere) { $pere = $this->getCodeSur4Chiffres($pere); $length = strlen($pere); @@ -306,17 +323,32 @@ class CodifThesaurusLoader extends Storm_Model_Loader { 'order'=> 'id_thesaurus']); } - $where = ''; - // while search result do not handle item novelty correctly - $to_exclude = [$this->fixedCodeOf('LibraryNovelty'), - $this->fixedCodeOf('AnnexeNovelty')]; + $to_exclude = [$this->fixedIdOf('LibraryNovelty'), + $this->fixedIdOf('AnnexeNovelty')]; if (!$all) - $to_exclude[] = $this->fixedCodeOf('Domain'); + $to_exclude[] = $this->fixedIdOf('Domain'); + + return $this->_findAllFromRootExcluding($to_exclude); + } + + + public function findAllForDomainCriteria() { + // novelty is a criteria in itself + // and no domains in domains + + return $this + ->_findAllFromRootExcluding([$this->fixedIdOf('RecordNovelty'), + $this->fixedIdOf('LibraryNovelty'), + $this->fixedIdOf('AnnexeNovelty'), + $this->fixedIdOf('Domain')]); + } - $where = sprintf('code not in ("%s") and ', implode('", "', $to_exclude)); - $where .= 'LENGTH(id_thesaurus) in (1,4)'; + protected function _findAllFromRootExcluding($to_exclude=[]) { + $where = sprintf('id_thesaurus not in ("%s") and LENGTH(id_thesaurus) in (1,%d)', + implode('", "', $to_exclude), + Class_CodifThesaurus::ID_KEY_LENGTH); return Class_CodifThesaurus::findAllBy(['where' => $where, 'order' => 'id_thesaurus']); diff --git a/library/Class/CodifThesaurusFixed.php b/library/Class/CodifThesaurusFixed.php index f71397a05ef6d01dc31f775e8a41b5ef449c1297..a8e25790274c75022b56f11740e7dcc5d3971852 100644 --- a/library/Class/CodifThesaurusFixed.php +++ b/library/Class/CodifThesaurusFixed.php @@ -27,6 +27,7 @@ class Class_CodifThesaurusFixed extends Class_Entity { 'CustomField' => ['CFCF', 'Custom fields', 'Champs personnalisés'], 'LibraryNovelty' => ['NNNN', 'Nouveauté par bibliothèque', 'Nouveauté par bibliothèque'], 'AnnexeNovelty' => ['NANA', 'Nouveauté par annexe', 'Nouveauté par annexe'], + 'RecordNovelty' => ['NRNR', 'Nouveauté', 'Nouveauté'], 'DigitalResources' => ['DRDR', 'Digital resources', 'Ressources numériques'], 'StreetName' => ['STRE', 'StreetName', 'Nom de rue'], 'LocationType' => ['LOCA', 'LocationType', 'Type de lieu'], diff --git a/library/Class/Notice.php b/library/Class/Notice.php index 32a107f66da7f214d8958ee8bd91b7971f614c2f..04d03289d20f3ddf76ac4cdd27dcf17a1f810680 100644 --- a/library/Class/Notice.php +++ b/library/Class/Notice.php @@ -153,15 +153,39 @@ class NoticeLoader extends Storm_Model_Loader { public function indexNoveltyFacets() { - $page = 1; - while($records = Class_Notice::findAllBy(['where' => 'match(facettes) against("+(HNNNN* HNANA*)" in boolean mode)', - 'limitPage' => [$page, 100]])) { - foreach($records as $record) - $record->updateNoveltyFacets(); - - $this->_cleanMemory(); - $page++; + $facets = ['HNNNN*', 'HNANA*']; + if ($novelty_thesaurus = Class_CodifThesaurus::recordNoveltyFor(true)) + $facets[] = $novelty_thesaurus->getFacetCode(); + $facets = implode(' ', $facets); + + $record_id = 0; + while ($records = $this->_findNoveltyRecordsFrom($facets, $record_id)) + $record_id = $this->_updateNovelty($records); + } + + + protected function _findNoveltyRecordsFrom($facets, $record_id) { + if (null === $record_id) + return []; + + $where = sprintf('match(facettes) against("+(%s)" in boolean mode) and id_notice > %d', + $facets, $record_id); + + return Class_Notice::findAllBy(['where' => $where, + 'order' => 'id_notice', + 'limit' => 100]); + } + + + protected function _updateNovelty($records) { + $record_id = null; + foreach($records as $record) { + $record->updateNoveltyFacets(); + $record_id = $record->getId(); } + $this->_cleanMemory(); + + return $record_id; } } @@ -1778,25 +1802,6 @@ class Class_Notice extends Storm_Model_Abstract { } - - public function getFacetCodesWithoutItemFacets() { - $filtered = [Class_Bib::CODE_FACETTE, - Class_CodifEmplacement::CODE_FACETTE, - Class_CodifSection::CODE_FACETTE, - Class_CodifAnnexe::CODE_FACETTE, - Class_CodifTypeDoc::CODE_FACETTE, - Class_Codification::CODE_DATE_NOUVEAUTE, - Class_Codification::CODE_AVAILABILITY]; - - return array_filter($this->getFacetCodes(), - function($code) use ($filtered) - { - return !in_array(substr($code, 0, 1), - $filtered); - }); - } - - protected function _fetchItemsToInjectInFacets() { if ($this->isPeriodiqueArticle() && ($linked_record = $this->getLinkedSerialRecord())) return $linked_record->getExemplaires(); @@ -1816,19 +1821,29 @@ class Class_Notice extends Storm_Model_Abstract { public function updateFacetsFromExemplaires() { - $facettes = $this->getFacetCodesWithoutItemFacets(); - $facettes []= Class_CodifTypeDoc::CODE_FACETTE. $this->getTypeDoc(); + $facets = Class_Notice_Facette::fromStringWithoutItemFacets($this->getFacettes()); + $facets = array_map(function($facet) { return $facet->getCle(); }, + $facets); + $facets[] = Class_CodifTypeDoc::CODE_FACETTE . $this->getTypeDoc(); + + $is_novelty = false; $date_nouveaute = ''; foreach($this->_fetchItemsToInjectInFacets() as $exemplaire) { - $facettes = array_merge($facettes, $exemplaire->getFacets()); + $facets = array_merge($facets, $exemplaire->getFacets()); + $date_nouveaute = ($exemplaire->getDateNouveaute() > $date_nouveaute) ? $exemplaire->getDateNouveaute() : $date_nouveaute; + + $is_novelty = $is_novelty || $exemplaire->isNouveaute(); } + if ($novelty_thesaurus = Class_CodifThesaurus::recordNoveltyFor($is_novelty)) + $facets[] = $novelty_thesaurus->getFacetCode(); + return $this - ->setFacettes(array_unique($facettes)) + ->setFacettes(array_unique($facets)) ->setDateCreation($date_nouveaute ? ($date_nouveaute . ' 00:00:00') : null); } @@ -1846,12 +1861,17 @@ class Class_Notice extends Storm_Model_Abstract { $this->deleteFacettes(implode(' ', $existings)); $facets = []; + $is_novelty = false; foreach($this->getExemplaires() as $item) if ($item->isNouveaute()) { $facets[] = Class_CodifThesaurus::findForItemLibraryNovelty($item); $facets[] = Class_CodifThesaurus::findForItemAnnexeNovelty($item); + $is_novelty = true; } + if ($novelty_thesaurus = Class_CodifThesaurus::recordNoveltyFor($is_novelty)) + $facets[] = $novelty_thesaurus->getFacetCode(); + $this->updateFacette(implode(' ', $facets))->save(); return $this; } diff --git a/library/Class/Notice/Facette.php b/library/Class/Notice/Facette.php index 7c8f320b8bffb4e03b15cf2205fb04c784c85c2e..96c33793baf6f484fc6c7378c47595aa8c6f69f8 100644 --- a/library/Class/Notice/Facette.php +++ b/library/Class/Notice/Facette.php @@ -19,13 +19,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class Class_Notice_Facette { - const NB_CHAR_THESAURUS = 4; - protected static $_instances = []; protected $_cle, - $_rubrique; + $_rubrique, + $_group_code, + $_value; public static function fromStringFiltered($facet_string, $callback) { @@ -35,6 +35,12 @@ class Class_Notice_Facette { } + public static function fromStringWithoutItemFacets($facet_string) { + return static::fromStringFiltered($facet_string, + function($facet) { return !$facet->isItem(); }); + } + + public static function parseFacettesFromNoticeField($str_facettes) { $items = array_filter(explode(' ', trim($str_facettes))); $facettes = []; @@ -88,12 +94,16 @@ class Class_Notice_Facette { public function getValue() { - return substr($this->_cle, 1); + return $this->_value = $this->_value + ? $this->_value + : substr($this->_cle, 1); } protected function getGroupCodeFromKey() { - return static::extractCodeRubrique($this->_cle); + return $this->_group_code = $this->_group_code + ? $this->_group_code + : static::extractCodeRubrique($this->_cle); } @@ -122,55 +132,98 @@ class Class_Notice_Facette { public function isNovelty() { return in_array(substr($this->getGroupCodeFromKey(), 1), [Class_CodifThesaurus::fixedIdOf('LibraryNovelty'), - Class_CodifThesaurus::fixedIdOf('AnnexeNovelty')]); + Class_CodifThesaurus::fixedIdOf('AnnexeNovelty'), + Class_CodifThesaurus::fixedIdOf('RecordNovelty')]); } public function isAvailability() { - return Class_Codification::CODE_AVAILABILITY == $this->getGroupCodeFromKey(); + return $this->isGroupCode(Class_Codification::CODE_AVAILABILITY); } public function isAuthor() { - return Class_CodifAuteur::CODE_FACETTE == $this->getGroupCodeFromKey(); + return $this->isGroupCode(Class_CodifAuteur::CODE_FACETTE); } public function isMatter() { - return Class_CodifMatiere::CODE_FACETTE == $this->getGroupCodeFromKey(); + return $this->isGroupCode(Class_CodifMatiere::CODE_FACETTE); } public function isDynamicFacet() { - return Class_CodifThesaurus::CODE_FACETTE === substr($this->_cle, 0, 1) + return $this->isThesaurus() && strlen($this->getValue()) === (Class_CodifThesaurus::ID_KEY_LENGTH * 2); } public function isDynamicFacetRoot() { - return Class_CodifThesaurus::CODE_FACETTE === substr($this->_cle, 0, 1) + return $this->isThesaurus() && strlen($this->getValue()) === Class_CodifThesaurus::ID_KEY_LENGTH; } public function isDocTypeFacet() { - return Class_CodifTypeDoc::CODE_FACETTE == $this->getGroupCodeFromKey(); + return $this->isGroupCode(Class_CodifTypeDoc::CODE_FACETTE); } public function isAnnexeFacet() { - return Class_CodifAnnexe::CODE_FACETTE == $this->getGroupCodeFromKey(); + return $this->isGroupCode(Class_CodifAnnexe::CODE_FACETTE); } public function isLibraryFacet() { - return Class_Bib::CODE_FACETTE == $this->getGroupCodeFromKey(); + return $this->isGroupCode(Class_Bib::CODE_FACETTE); } public function isDomainFacet() { - $code = $this->getGroupCodeFromKey(); - return Class_Catalogue::CODE_FACETTE == $code - || Class_CodifThesaurus::CODE_FACETTE == $this->_cle[0]; + return $this->isGroupCode(Class_Catalogue::CODE_FACETTE) || $this->isThesaurus(); + } + + + public function isLocationFacet() { + return $this->isGroupCode(Class_CodifEmplacement::CODE_FACETTE); + } + + + public function isSectionFacet() { + return $this->isGroupCode(Class_CodifSection::CODE_FACETTE); + } + + + public function isThesaurus() { + return Class_CodifThesaurus::CODE_FACETTE === substr($this->_cle, 0, 1); + } + + + public function isRecordNoveltyFacet() { + return $this->isDynamicFacetUnder(Class_CodifThesaurus::fixedIdOf('RecordNovelty')); + } + + + public function isDynamicFacetUnder($root_code) { + return $this->isDynamicFacet() && substr($this->getGroupCodeFromKey(), 1) === $root_code; + } + + + public function isItem() { + return + $this->isLibraryFacet() + || $this->isLocationFacet() + || $this->isSectionFacet() + || $this->isAnnexeFacet() + || $this->isDocTypeFacet() + || $this->isGroupCode(Class_Codification::CODE_DATE_NOUVEAUTE) + || $this->isGroupCode(Class_Codification::CODE_AVAILABILITY) + || $this->isRecordNoveltyFacet() + ; + } + + + public function isGroupCode($code) { + return $this->getGroupCodeFromKey() === $code; } } \ No newline at end of file diff --git a/library/ZendAfi/Form/Configuration/Domain.php b/library/ZendAfi/Form/Configuration/Domain.php index 805b247c442f592b930a2184620cca0a50bc0431..99eaa12bdb3086885d065b99fa62bd2b23d331a3 100644 --- a/library/ZendAfi/Form/Configuration/Domain.php +++ b/library/ZendAfi/Form/Configuration/Domain.php @@ -160,7 +160,7 @@ class ZendAfi_Form_Configuration_Domain extends ZendAfi_Form { ; $thesaurus_elements = []; - foreach(Class_CodifThesaurus::getIndices('root') as $thesaurus) { + foreach(Class_CodifThesaurus::findAllForDomainCriteria() as $thesaurus) { $name = $thesaurus->getIdThesaurus(); $this->addElement('listeSuggestion', $name, diff --git a/scripts/reindex_local_items_facets.php b/scripts/reindex_local_items_facets.php new file mode 100644 index 0000000000000000000000000000000000000000..e1f660ec9c263aa5cb183712495e21ee2749dc17 --- /dev/null +++ b/scripts/reindex_local_items_facets.php @@ -0,0 +1,59 @@ +<?php +error_reporting(E_ALL^E_DEPRECATED); +require __DIR__ . '/../console.php'; + +echo "\n\nWelcome to the iReindex Items Facets 2000 X tool by @patbator, proudly RTed by @lla \n\n"; + +echo "\n\nWill update items facets of " . Class_Notice::count() . " records in database\n\n"; + +class Script_ItemsFacets_Updater { + use Trait_MemoryCleaner; + + protected + $_adapter, + $_last_id = 0, + $_page = 1; + + public function __construct() { + $this->_adapter = Zend_Db_Table_Abstract::getDefaultAdapter(); + } + + + public function run() { + while ($records = Class_Notice::findAllBy(['where' => 'id_notice > ' . (int)$this->_last_id, + 'limit' => '1000'])) + $this->_runPage($records); + + return $this; + } + + + protected function _runPage($records) { + echo "\npage: ". $this->_page ."\n"; + $this->_page++; + + foreach($records as $record) + $this->_runOne($record); + + $this->_last_id = $record->getId(); + $this->_cleanMemory(); + return $this; + } + + + protected function _runOne($record) { + $old = $record->getFacettes(); + $record->updateFacetsFromExemplaires(); + if ($old != $record->getFacettes()) + $record->save(); + + echo '.'; + + return $this; + } +} + +$updater = new Script_ItemsFacets_Updater; +$updater->run(); + +echo "\n\nDONE !!!!\n\n"; diff --git a/tests/application/modules/admin/controllers/CatalogueControllerTest.php b/tests/application/modules/admin/controllers/CatalogueControllerTest.php index 4275650e7e8098756e4ede6a8a045895836e7328..11f6cbf10560ed1f9ba7dd8d02fcf12d947f8785 100644 --- a/tests/application/modules/admin/controllers/CatalogueControllerTest.php +++ b/tests/application/modules/admin/controllers/CatalogueControllerTest.php @@ -698,12 +698,12 @@ class CatalogueControllerEditCatalogueTest extends AdminCatalogueControllerTestC $this->onLoaderOfModel('Class_CodifThesaurus') ->whenCalled('findAllBy') - ->with(['where' => 'code not in ("Nouveauté par bibliothèque", "Nouveauté par annexe", "Catalogue") and LENGTH(id_thesaurus) in (1,4)', + ->with(['where' => 'id_thesaurus not in ("NRNR", "NNNN", "NANA", "CCCC") and LENGTH(id_thesaurus) in (1,4)', 'order' => 'id_thesaurus']) - ->answers([Class_CodifThesaurus::find(1), - Class_CodifThesaurus::find(2)]); + ->answers([Class_CodifThesaurus::find(1), Class_CodifThesaurus::find(2)]) + ; - $this->dispatch('/admin/catalogue/edit/id_catalogue/6', true); + $this->dispatch('/admin/catalogue/edit/id_catalogue/6'); } diff --git a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php index 79877281330f31a9fc6add9bbd5a2ec6eedfbef4..52b1515cf5f64b03fc98f834d6508cd1b8fa65cf 100644 --- a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php +++ b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php @@ -834,8 +834,9 @@ class NoticeAjaxControllerExemplairesWithOtherAnnexTestCase extends AbstractCont /** @test */ public function facetsShouldBeUpdatedWithAnnex21() { - $this->dispatch('noticeajax/exemplaires/id/123', true); - $this->assertEquals('D78092 A3029 A9751 A117014 A117015 M37414 G464 HNNNN0002 HNANA0002 T0 B6 SA9 Eemplacement de test Y21 V6', Class_notice::find(123)->getFacettes()); + $this->dispatch('noticeajax/exemplaires/id/123'); + $this->assertEquals('D78092 A3029 A9751 A117014 A117015 M37414 G464 HNNNN0002 HNANA0002 T0 B6 SA9 Eemplacement de test Y21 V6 HNRNR0001', + Class_notice::find(123)->getFacettes()); } } diff --git a/tests/library/Class/CodifThesaurusTest.php b/tests/library/Class/CodifThesaurusTest.php index 8957f4d7e1d614747fdb26c063f3228ceaf82e35..88166946bbbac6de5a56eb8d15fc1a41ca5bc7db 100644 --- a/tests/library/Class/CodifThesaurusTest.php +++ b/tests/library/Class/CodifThesaurusTest.php @@ -171,8 +171,8 @@ class CodifThesaurusGetIndicesRootTest extends ModelTestCase { /** @test */ public function shouldExcludeNoveltyAndDomains() { - Class_CodifThesaurus::getIndices('root', false); - $expected_params = ['where' => 'code not in ("Nouveauté par bibliothèque", "Nouveauté par annexe", "Catalogue") and LENGTH(id_thesaurus) in (1,4)', + Class_CodifThesaurus::getIndices('root'); + $expected_params = ['where' => 'id_thesaurus not in ("NNNN", "NANA", "CCCC") and LENGTH(id_thesaurus) in (1,4)', 'order' => 'id_thesaurus']; $this->assertEquals($expected_params, @@ -183,7 +183,7 @@ class CodifThesaurusGetIndicesRootTest extends ModelTestCase { /** @test */ public function shouldExcludeNoveltyButNotDomain() { Class_CodifThesaurus::getIndices('root', true); - $expected_params = ['where' => 'code not in ("Nouveauté par bibliothèque", "Nouveauté par annexe") and LENGTH(id_thesaurus) in (1,4)', + $expected_params = ['where' => 'id_thesaurus not in ("NNNN", "NANA") and LENGTH(id_thesaurus) in (1,4)', 'order' => 'id_thesaurus']; $this->assertEquals($expected_params, Class_CodifThesaurus::getFirstAttributeForLastCallOn('findAllBy')); } diff --git a/tests/library/Class/NoticeNoveltyTest.php b/tests/library/Class/NoticeNoveltyTest.php index b13299a566fa9bbe6cbb8989c4ed643a9df48c27..92683e8fe15c8874f734db0a6dd92e9af377f2bf 100644 --- a/tests/library/Class/NoticeNoveltyTest.php +++ b/tests/library/Class/NoticeNoveltyTest.php @@ -38,33 +38,42 @@ class NoticeNoveltyTest extends ModelTestCase{ 'libelle' => 'My Annexe']); - $this + $record_12 = $this ->fixture('Class_Notice', ['id' => 12, 'facettes' => 'T1 B4', - 'date_creation' => '2017-02-28']) - ->addExemplaire($this->fixture('Class_Exemplaire', - ['id' => 90000, - 'id_bib' => 4, - 'annexe' => 2, - 'date_nouveaute' => '2017-02-28'])) - ->assertSave(); - - $this + 'date_creation' => '2017-02-28']); + $record_12->addExemplaire($this->fixture('Class_Exemplaire', + ['id' => 90000, + 'id_bib' => 4, + 'annexe' => 2, + 'date_nouveaute' => '2017-02-28'])) + ->assertSave(); + + $record_15 = $this ->fixture('Class_Notice', ['id' => 15, 'facettes' => 'T1 B4 HNNNN0001', - 'date_creation' => '']) - ->addExemplaire($this->fixture('Class_Exemplaire', - ['id' => 99999, - 'id_bib' => 4, - 'annexe' => 2, - 'date_nouveaute' => '2015-02-28'])) - ->assertSave(); + 'date_creation' => '']); + $record_15->addExemplaire($this->fixture('Class_Exemplaire', + ['id' => 99999, + 'id_bib' => 4, + 'annexe' => 2, + 'date_nouveaute' => '2015-02-28'])) + ->assertSave(); - $this->onLoaderOfModel('Class_Notice'); Class_Notice::setMemoryCleaner(function() {}); + $this->onLoaderOfModel('Class_Notice') + ->whenCalled('findAllBy') + ->willDo(function($params) use($record_12, $record_15) + { + if ($params['where'] == 'match(facettes) against("+(HNNNN* HNANA* HNRNR0001)" in boolean mode) and id_notice > 0') + return [$record_12, $record_15]; + + return []; + }); + Class_Notice::indexNoveltyFacets(); } @@ -72,21 +81,22 @@ class NoticeNoveltyTest extends ModelTestCase{ /** @test */ public function record12ShouldHaveNoveltyFacet() { Class_Notice::find(12)->updateNoveltyFacets(); - $this->assertEquals('T1 B4 HNNNN0001 HNANA0001', + $this->assertEquals('T1 B4 HNNNN0001 HNANA0001 HNRNR0001', Class_Notice::find(12)->getFacettes()); } /** @test */ public function record15ShouldNotHaveNoveltyFacet() { - $this->assertEquals('T1 B4', Class_Notice::find(15)->getFacettes()); + $this->assertEquals('T1 B4 HNRNR0002', Class_Notice::find(15)->getFacettes()); } /** @test */ public function indexShouldNotFetchAllRecords() { - $this->assertEquals(['where' => 'match(facettes) against("+(HNNNN* HNANA*)" in boolean mode)', - 'limitPage' => [2, 100]], + $this->assertEquals(['where' => 'match(facettes) against("+(HNNNN* HNANA* HNRNR0001)" in boolean mode) and id_notice > 15', + 'order' => 'id_notice', + 'limit' => 100], Class_Notice::getFirstAttributeForLastCallOn('findAllBy')); } } diff --git a/tests/library/Class/NoticeTest.php b/tests/library/Class/NoticeTest.php index 530dc080800a80752a22d37495703365a0fa5d89..874919d17d9527ac30f0e26776d8b96a64b69b51 100644 --- a/tests/library/Class/NoticeTest.php +++ b/tests/library/Class/NoticeTest.php @@ -1010,7 +1010,8 @@ class NoticeUpdateFacetsFromItemsTest extends ModelTestCase { /** @test */ public function recordFacetsShouldContainsNoveltyForRoubaixAndNoveltyForLille() { - $this->assertEquals('T0 B10 YROUB HNNNN0001 HNANA0001 B11 HNNNN0002', Class_Notice::find(5)->getFacettes()); + $this->assertEquals('T0 B10 YROUB HNNNN0001 HNANA0001 B11 HNNNN0002 HNRNR0001', + Class_Notice::find(5)->getFacettes()); } } diff --git a/tests/scenarios/NoveltyFacet/NoveltyFacetTest.php b/tests/scenarios/NoveltyFacet/NoveltyFacetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a53cbb29bb963345fcb5b7c18c3f2c74d73915ad --- /dev/null +++ b/tests/scenarios/NoveltyFacet/NoveltyFacetTest.php @@ -0,0 +1,199 @@ +<?php +/** + * Copyright (c) 2012-2020, 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 NoveltyFacetSearchResultConfigTest extends Admin_AbstractControllerTestCase { + protected $_storm_default_to_volatile = true; + + public function setUp() { + parent::setUp(); + Class_CodifThesaurus::ensureRecordNovelty(); + } + + + /** @test */ + public function noveltyFacetShouldBeAvailableInHistoric() { + $this->dispatch('/admin/modules/recherche/config/site/type_module/recherche/id_profil/1/action1/resultat/action2/simple'); + $this->_assertNoveltyIsAvailable(); + } + + + /** @test */ + public function noveltyFacetShouldBeAvailableInTemplates() { + $id = (new Intonation_Template)->tryOn(Class_Profil::getCurrentProfil()); + $this->dispatch('/admin/widget/edit-action/id/recherche_resultat_simple/id_profil/' . $id); + $this->_assertNoveltyIsAvailable(); + } + + + protected function _assertNoveltyIsAvailable() { + $this->assertXPathContentContains('//div[@data-heading="facettes"]//li[@data-id="HNRNR"]', + 'Nouveauté'); + } +} + + + + +class NoveltyFacetDomainEditTest extends Admin_AbstractControllerTestCase { + protected $_storm_default_to_volatile = true; + + + public function setUp() { + parent::setUp(); + Class_CodifThesaurus::ensureRecordNovelty(); + $this->onLoaderOfModel('Class_CodifThesaurus'); + $this->dispatch('/admin/catalogue/add'); + } + + + /** @test */ + public function pageShouldNotContainRecordNoveltyInput() { + $this->assertContains('id_thesaurus not in ("NRNR", "NNNN", "NANA", "CCCC")', + Class_CodifThesaurus::getFirstAttributeForLastCallOn('findAllBy')['where']); + } +} + + + + +class NoveltyFacetSearchResultSimpleTest extends AbstractControllerTestCase { + protected $_storm_default_to_volatile = true; + + + public function setUp() { + parent::setUp(); + Class_CodifThesaurus::ensureRecordNovelty(); + + $this->fixture('Class_Notice', ['id' => 2]); + + Class_Profil::getCurrentProfil() + ->setModulePreference('recherche', 'resultatsimple', 'facettes_codes', 'HNRNR'); + } + + + public function facets() { + return [['HNRNR0001', 'Oui'], + ['HNRNR0002', 'Non']]; + } + + + /** + * @test + * @dataProvider facets + */ + public function withFacetPageShouldContainLinkToFilterByNovelty($facet, $label) { + Zend_Registry::set('sql', + $this->mock() + ->whenCalled('fetchAll') + ->with('select id_notice, facettes from notices Where type=1', true, false) + ->answers([[2, $facet]])); + + $this->dispatch('/opac/recherche/simple/expressionRecherche/*'); + $this->assertXPathContentContains('//a[contains(@href, "/facette/'. $facet .'")]', $label); + } +} + + + + +abstract class NoveltyFacetRecordUpdateTestCase extends ModelTestCase { + protected $_record; + + public function setUp() { + parent::setUp(); + Class_CodifThesaurus::ensureRecordNovelty(); + $this->_record = $this->fixture('Class_Notice', + ['id' => 2, + 'type_doc' => Class_TypeDoc::LIVRE]); + Class_Exemplaire::setTimeSource(new TimeSourceForTest('2021-01-14 16:55:16')); + } + + + public function tearDown() { + Class_Exemplaire::setTimeSource(null); + parent::tearDown(); + } + + + /** @test */ + public function notNoveltyShouldBecomeNovelty() { + $this->_recordFacetAndNovelty('T1 HNRNR0002', '2021-02-19'); + $this->_updateRecord(); + $this->assertContains('HNRNR0001', $this->_record->getFacettes()); + $this->assertNotContains('HNRNR0002', $this->_record->getFacettes()); + } + + + /** @test */ + public function noveltyShouldBecomeNotNovelty() { + $this->_recordFacetAndNovelty('T1 HNRNR0001', ''); + $this->_updateRecord(); + $this->assertContains('HNRNR0002', $this->_record->getFacettes()); + $this->assertNotContains('HNRNR0001', $this->_record->getFacettes()); + } + + + protected function _recordFacetAndNovelty($facets, $novelty_date) { + $this->_record + ->setFacettes($facets) + ->setExemplaires([$this->fixture('Class_Exemplaire', + ['id' => 3, + 'date_nouveaute' => $novelty_date])]) + ->assertSave(); + } + + + protected function _updateRecord() { + } +} + + + + +class NoveltyFacetUpdateFacetsFromExemplairesTest extends NoveltyFacetRecordUpdateTestCase { + protected function _updateRecord() { + $this->_record->updateFacetsFromExemplaires(); + } +} + + + + +class NoveltyFacetUpdateNoveltyFacetsTest extends NoveltyFacetRecordUpdateTestCase { + protected function _updateRecord() { + $this->_record->updateNoveltyFacets(); + } +} + + + + +class NoveltyFacetIndexTest extends ModelTestCase { + /** @test */ + public function findAllByShouldContainRecordNoveltyFacet() { + Class_CodifThesaurus::ensureRecordNovelty(); + $this->onLoaderOfModel('Class_Notice'); + Class_Notice::indexNoveltyFacets(); + $this->assertContains('+(HNNNN* HNANA* HNRNR0001)', + Class_Notice::getFirstAttributeForLastCallOn('findAllBy')['where']); + } +} \ No newline at end of file