3 # Tests for Koha/SearchEngine/Search
7 use Test::More tests => 2;
18 use C4::AuthoritiesMarc qw( AddAuthority DelAuthority merge );
19 use C4::Biblio qw( ModZebra ModBiblio ModBiblioMarc DelBiblio );
20 use C4::Circulation qw( MarkIssueReturned AddReturn LostItem );
21 use C4::Items qw( ModDateLastSeen ModItemTransfer );
23 use Koha::SearchEngine::Elasticsearch;
24 use Koha::SearchEngine::Indexer;
26 use t::lib::TestBuilder;
29 my $schema = Koha::Database->new->schema;
30 my $builder = t::lib::TestBuilder->new;
32 $schema->storage->txn_begin;
34 subtest 'Test indexer object creation' => sub {
37 t::lib::Mocks::mock_preference( 'SearchEngine', 'Zebra' );
38 my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX });
39 is( ref $indexer, 'Koha::SearchEngine::Zebra::Indexer', 'We get the correct class for Zebra biblios');
40 $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::AUTHORITIES_INDEX });
41 is( ref $indexer, 'Koha::SearchEngine::Zebra::Indexer', 'We get the correct class for Zebra authorities');
43 t::lib::Mocks::mock_preference( 'SearchEngine', 'Elasticsearch' );
47 eval { Koha::SearchEngine::Elasticsearch->get_elasticsearch_params; };
49 skip 'Elasticsearch configuration not available', 4
52 $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX });
53 is( ref $indexer, 'Koha::SearchEngine::Elasticsearch::Indexer', 'We get the correct class for Elasticsearch biblios');
54 ok( $indexer->index_name =~ /biblios$/, "The index is set correctly for biblios");
55 $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::AUTHORITIES_INDEX });
56 is( ref $indexer, 'Koha::SearchEngine::Elasticsearch::Indexer', 'We get the correct class for Elasticsearch authorities');
57 ok( $indexer->index_name =~ /authorities$/, "The index is set correctly for authorities");
62 subtest 'Test indexer calls' => sub {
65 my @engines = ('Zebra');
66 eval { Koha::SearchEngine::Elasticsearch->get_elasticsearch_params; };
67 push @engines, 'Elasticsearch' unless $@;
69 skip 'Elasticsearch configuration not available', 20
70 if scalar @engines == 1;
73 t::lib::Mocks::mock_preference( 'BiblioAddsAuthorities', 0 );
75 for my $engine ( @engines ){
76 t::lib::Mocks::mock_preference( 'SearchEngine', $engine );
77 my $mock_index = Test::MockModule->new("Koha::SearchEngine::".$engine."::Indexer");
79 my $biblionumber1 = $builder->build_sample_biblio()->biblionumber;
80 my $biblionumber2 = $builder->build_sample_biblio()->biblionumber;
82 my $mock_zebra = Test::MockModule->new("Koha::SearchEngine::Zebra::Indexer");
83 $mock_zebra->mock( ModZebra => sub { warn "ModZebra"; } );
84 my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX });
86 $indexer->index_records([$biblionumber1,$biblionumber1],"specialUpdate","biblioserver",undef);
87 } ["ModZebra","ModZebra"],"ModZebra called for each record being indexed for $engine";
89 $mock_index->mock( index_records => sub {
91 my ($package, undef, undef) = caller;
95 my $auth = MARC::Record->new;
98 $authid = AddAuthority( $auth, undef, 'TOPIC_TERM' );
99 } [$engine,"C4::AuthoritiesMarc"], "index_records is called for $engine is called when adding authority";
102 $authid = DelAuthority({ authid => $authid, skip_merge => 1 });
103 } [$engine,"C4::AuthoritiesMarc"], "index_records is called for $engine is called when adding authority";
109 $biblio = $builder->build_sample_biblio();
110 $biblio2 = $builder->build_sample_biblio();
111 $biblio3 = $builder->build_sample_biblio();
112 } [$engine,'C4::Biblio',$engine,'C4::Biblio',$engine,'C4::Biblio'], "index_records is called for $engine when adding a biblio (ModBiblioMarc)";
121 $item = $builder->build_sample_item({
122 biblionumber => $biblio->biblionumber,
123 onloan => '2020-02-02',
124 datelastseen => '2020-01-01',
125 replacementprice => 0
127 $item2 = $builder->build_sample_item({
128 biblionumber => $biblio->biblionumber,
129 onloan => '2020-12-12',
130 datelastseen => '2020-11-11',
131 replacementprice => 0
133 $item3 = $builder->build_sample_item({biblionumber => $biblio->biblionumber});
134 $item4 = $builder->build_sample_item({biblionumber => $biblio->biblionumber});
135 $item5 = $builder->build_sample_item({biblionumber => $biblio3->biblionumber});
136 $item6 = $builder->build_sample_item({biblionumber => $biblio3->biblionumber});
137 } [$engine,"Koha::Item",
138 $engine,"Koha::Item",
139 $engine,"Koha::Item",
140 $engine,"Koha::Item",
141 $engine,"Koha::Item",
142 $engine,"Koha::Item"], "index_records is called for $engine when adding an item (Item->store)";
144 $item->store({ skip_record_index => 1 });
145 } undef, "index_records is not called for $engine when adding an item (Item->store) if skip_record_index passed";
147 my $issue = $builder->build({
150 itemnumber => $item->itemnumber
153 my $issue2 = $builder->build({
156 itemnumber => $item2->itemnumber
160 MarkIssueReturned( $issue->{borrowernumber}, $item->itemnumber);
161 } [$engine,"Koha::Item"], "index_records is called for $engine when calling MarkIssueReturned";
163 MarkIssueReturned( $issue2->{borrowernumber}, $item2->itemnumber, undef, undef, { skip_record_index => 1});
164 } undef, "index_records is not called for $engine when calling MarkIssueReturned if skip_record_index passed";
167 AddReturn($item->barcode, $item->homebranch, 0, undef);
168 } [$engine,'C4::Circulation'], "index_records is called once for $engine when calling AddReturn if item not issued";
169 $issue = $builder->build({
172 itemnumber => $item->itemnumber
176 AddReturn($item->barcode, $item->homebranch, 0, undef);
177 } [$engine,'C4::Circulation'], "index_records is called once for $engine when calling AddReturn if item not issued";
180 $item3->move_to_biblio($biblio2);
181 } [$engine,"Koha::Item",$engine,"Koha::Item"], "index_records is called twice for $engine when moving an item to another biblio (Item->move_to_biblio)";
183 $item4->move_to_biblio($biblio2, { skip_record_index => 1 });
184 } undef, "index_records is not called for $engine when moving an item to another biblio (Item->move_to_biblio) if skip_record_index passed";
187 $biblio->items->move_to_biblio($biblio2);
188 } [$engine,"Koha::Items",$engine,"Koha::Items"], "index_records is called for from and to biblios for $engine when adopting items (Biblio->items->move_to_biblio(Biblio)";
190 my $items = Koha::Items->search({ itemnumber => [ $item2->itemnumber, $item5->itemnumber, $item6->itemnumber ] });
192 $items->move_to_biblio($biblio);
193 } [$engine,"Koha::Items",$engine,"Koha::Items",$engine,"Koha::Items"], "index_records is called for all from and to biblios for $engine when adopting items (Items->move_to_biblio(Biblio)";
198 itemnumber => $item->itemnumber
201 $item->onloan('2000-01-01')->store({ skip_record_index => 1 });
203 LostItem( $item->itemnumber, "tests", 1);
204 } [$engine,"Koha::Item"], "index_records is called for $engine when calling LostItem with 'force_mark_returned'";
208 itemnumber => $item->itemnumber
211 $item->onloan('2000-01-01')->store({ skip_record_index => 1 });
213 LostItem( $item->itemnumber, "tests", 1, { skip_record_index => 1 });
214 } undef, "index_records is not called for $engine when calling LostItem with 'force_mark_returned' if skip_record_index";
216 $item->datelastseen('2001-01-01')->store({skip_record_index=>1});
218 my $t1 = ModDateLastSeen( $item->itemnumber, 1, undef );
219 } [$engine, "Koha::Item"], "index_records is called for $engine when calling ModDateLastSeen";
221 ModDateLastSeen( $item->itemnumber, 1, { skip_record_index =>1 } );
222 } undef, "index_records is not called for $engine when calling ModDateLastSeen if skip_record_index";
225 ModItemTransfer( $item->itemnumber, $item2->homebranch, $item->homebranch,'Manual');
226 } [$engine,"Koha::Item"], "index_records is called for $engine when calling ModItemTransfer";
228 ModItemTransfer( $item->itemnumber, $item->homebranch, $item2->homebranch,'Manual',{skip_record_index=>1});
229 } undef, "index_records is not called for $engine when calling ModItemTransfer with skip_record_index";
233 } [$engine,"Koha::Item"], "index_records is called for $engine when deleting an item (Item->delete)";
235 $item2->delete({ skip_record_index => 1 });
236 } undef, "index_records is not called for $engine when adding an item (Item->store) if skip_record_index passed";
239 DelBiblio( $biblio3->biblionumber );
240 } [$engine, "C4::Biblio"], "index_records is called for $engine when calling DelBiblio";
242 DelBiblio( $biblio3->biblionumber, { skip_record_index =>1 });
243 } undef, "index_records is not called for $engine when calling DelBiblio if skip_record_index passed";
249 $schema->storage->txn_rollback;