Bug 26984: Make tests pass if AnonymousPatron is set
[koha.git] / t / db_dependent / Koha / Biblio.t
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19
20 use Test::More tests => 12;
21
22 use C4::Biblio;
23 use Koha::Database;
24 use Koha::Acquisition::Orders;
25
26 use t::lib::TestBuilder;
27 use t::lib::Mocks;
28
29 BEGIN {
30     use_ok('Koha::Biblio');
31     use_ok('Koha::Biblios');
32 }
33
34 my $schema  = Koha::Database->new->schema;
35 my $builder = t::lib::TestBuilder->new;
36
37 subtest 'metadata() tests' => sub {
38
39     plan tests => 4;
40
41     $schema->storage->txn_begin;
42
43     my $title = 'Oranges and Peaches';
44
45     my $record = MARC::Record->new();
46     my $field = MARC::Field->new('245','','','a' => $title);
47     $record->append_fields( $field );
48     my ($biblionumber) = C4::Biblio::AddBiblio($record, '');
49
50     my $biblio = Koha::Biblios->find( $biblionumber );
51     is( ref $biblio, 'Koha::Biblio', 'Found a Koha::Biblio object' );
52
53     my $metadata = $biblio->metadata;
54     is( ref $metadata, 'Koha::Biblio::Metadata', 'Method metadata() returned a Koha::Biblio::Metadata object' );
55
56     my $record2 = $metadata->record;
57     is( ref $record2, 'MARC::Record', 'Method record() returned a MARC::Record object' );
58
59     is( $record2->field('245')->subfield("a"), $title, 'Title in 245$a matches title from original record object' );
60
61     $schema->storage->txn_rollback;
62 };
63
64 subtest 'hidden_in_opac() tests' => sub {
65
66     plan tests => 4;
67
68     $schema->storage->txn_begin;
69
70     my $biblio = $builder->build_sample_biblio();
71
72     ok( !$biblio->hidden_in_opac({ rules => { withdrawn => [ 2 ] } }), 'Biblio not hidden if there is no item attached' );
73
74     my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
75     my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
76
77     $item_1->withdrawn( 1 )->store->discard_changes;
78     $item_2->withdrawn( 1 )->store->discard_changes;
79
80     ok( !$biblio->hidden_in_opac({ rules => { withdrawn => [ 2 ] } }), 'Biblio not hidden' );
81
82     $item_2->withdrawn( 2 )->store->discard_changes;
83     $biblio->discard_changes; # refresh
84
85     ok( !$biblio->hidden_in_opac({ rules => { withdrawn => [ 2 ] } }), 'Biblio not hidden' );
86
87     $item_1->withdrawn( 2 )->store->discard_changes;
88     $biblio->discard_changes; # refresh
89
90     ok( $biblio->hidden_in_opac({ rules => { withdrawn => [ 2 ] } }), 'Biblio hidden' );
91
92     $schema->storage->txn_rollback;
93 };
94
95 subtest 'items() tests' => sub {
96
97     plan tests => 4;
98
99     $schema->storage->txn_begin;
100
101     my $biblio = $builder->build_sample_biblio();
102
103     is( $biblio->items->count, 0, 'No items, count is 0' );
104
105     my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
106     my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
107
108     my $items = $biblio->items;
109     is( ref($items), 'Koha::Items', 'Returns a Koha::Items resultset' );
110     is( $items->count, 2, 'Two items in resultset' );
111
112     my @items = $biblio->items->as_list;
113     is( scalar @items, 2, 'Same result, but in list context' );
114
115     $schema->storage->txn_rollback;
116
117 };
118
119 subtest 'get_coins and get_openurl' => sub {
120
121     plan tests => 4;
122
123     $schema->storage->txn_begin;
124
125     my $builder = t::lib::TestBuilder->new;
126     my $biblio = $builder->build_sample_biblio({
127             title => 'Title 1',
128             author => 'Author 1'
129         });
130     is(
131         $biblio->get_coins,
132         'ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&amp;rft.genre=book&amp;rft.btitle=Title%201&amp;rft.au=Author%201',
133         'GetCOinsBiblio returned right metadata'
134     );
135
136     my $record = MARC::Record->new();
137     $record->append_fields( MARC::Field->new('100','','','a' => 'Author 2'), MARC::Field->new('880','','','a' => 'Something') );
138     my ( $biblionumber ) = C4::Biblio::AddBiblio($record, '');
139     my $biblio_no_title = Koha::Biblios->find($biblionumber);
140     is(
141         $biblio_no_title->get_coins,
142         'ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&amp;rft.genre=book&amp;rft.au=Author%202',
143         'GetCOinsBiblio returned right metadata if biblio does not have a title'
144     );
145
146     t::lib::Mocks::mock_preference("OpenURLResolverURL", "https://koha.example.com/");
147     is(
148         $biblio->get_openurl,
149         'https://koha.example.com/?ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&amp;rft.genre=book&amp;rft.btitle=Title%201&amp;rft.au=Author%201',
150         'Koha::Biblio->get_openurl returned right URL'
151     );
152
153     t::lib::Mocks::mock_preference("OpenURLResolverURL", "https://koha.example.com/?client_id=ci1");
154     is(
155         $biblio->get_openurl,
156         'https://koha.example.com/?client_id=ci1&amp;ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&amp;rft.genre=book&amp;rft.btitle=Title%201&amp;rft.au=Author%201',
157         'Koha::Biblio->get_openurl returned right URL'
158     );
159
160     $schema->storage->txn_rollback;
161 };
162
163 subtest 'is_serial() tests' => sub {
164
165     plan tests => 3;
166
167     $schema->storage->txn_begin;
168
169     my $biblio = $builder->build_sample_biblio();
170
171     $biblio->serial( 1 )->store->discard_changes;
172     ok( $biblio->is_serial, 'Bibliographic record is serial' );
173
174     $biblio->serial( 0 )->store->discard_changes;
175     ok( !$biblio->is_serial, 'Bibliographic record is not serial' );
176
177     my $record = $biblio->metadata->record;
178     $record->leader('00142nas a22     7a 4500');
179     ModBiblio($record, $biblio->biblionumber );
180     $biblio = Koha::Biblios->find($biblio->biblionumber);
181
182     ok( $biblio->is_serial, 'Bibliographic record is serial' );
183
184     $schema->storage->txn_rollback;
185 };
186
187 subtest 'pickup_locations' => sub {
188     plan tests => 8;
189
190     $schema->storage->txn_begin;
191
192     my $nb_libraries = Koha::Libraries->count;
193     Koha::CirculationRules->search->delete;
194     Koha::CirculationRules->set_rules(
195         {
196             categorycode => undef,
197             itemtype     => undef,
198             branchcode   => undef,
199             rules        => {
200                 reservesallowed => 25,
201             }
202         }
203     );
204
205     my $root1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
206     my $root2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
207     my $root3 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
208
209     my $library1 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
210     my $library2 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
211     my $library3 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 0 } } );
212     my $library4 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
213     my $library5 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
214     my $library6 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
215     my $library7 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
216     my $library8 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 0 } } );
217
218     our @branchcodes = map { $_->branchcode } ($library1, $library2, $library3, $library4, $library5, $library6, $library7, $library8);
219
220     Koha::CirculationRules->set_rules(
221         {
222             branchcode => $library1->branchcode,
223             itemtype   => undef,
224             rules => {
225                 holdallowed => 1,
226                 hold_fulfillment_policy => 'any',
227                 returnbranch => 'any'
228             }
229         }
230     );
231
232     Koha::CirculationRules->set_rules(
233         {
234             branchcode => $library2->branchcode,
235             itemtype   => undef,
236             rules => {
237                 holdallowed => 3,
238                 hold_fulfillment_policy => 'holdgroup',
239                 returnbranch => 'any'
240             }
241         }
242     );
243
244     Koha::CirculationRules->set_rules(
245         {
246             branchcode => $library3->branchcode,
247             itemtype   => undef,
248             rules => {
249                 holdallowed => 3,
250                 hold_fulfillment_policy => 'patrongroup',
251                 returnbranch => 'any'
252             }
253         }
254     );
255
256     Koha::CirculationRules->set_rules(
257         {
258             branchcode => $library4->branchcode,
259             itemtype   => undef,
260             rules => {
261                 holdallowed => 2,
262                 hold_fulfillment_policy => 'holdingbranch',
263                 returnbranch => 'any'
264             }
265         }
266     );
267
268     Koha::CirculationRules->set_rules(
269         {
270             branchcode => $library5->branchcode,
271             itemtype   => undef,
272             rules => {
273                 holdallowed => 2,
274                 hold_fulfillment_policy => 'homebranch',
275                 returnbranch => 'any'
276             }
277         }
278     );
279
280     Koha::CirculationRules->set_rules(
281         {
282             branchcode => $library6->branchcode,
283             itemtype   => undef,
284             rules => {
285                 holdallowed => 1,
286                 hold_fulfillment_policy => 'holdgroup',
287                 returnbranch => 'any'
288             }
289         }
290     );
291
292     Koha::CirculationRules->set_rules(
293         {
294             branchcode => $library7->branchcode,
295             itemtype   => undef,
296             rules => {
297                 holdallowed => 3,
298                 hold_fulfillment_policy => 'holdingbranch',
299                 returnbranch => 'any'
300             }
301         }
302     );
303
304
305     Koha::CirculationRules->set_rules(
306         {
307             branchcode => $library8->branchcode,
308             itemtype   => undef,
309             rules => {
310                 holdallowed => 2,
311                 hold_fulfillment_policy => 'patrongroup',
312                 returnbranch => 'any'
313             }
314         }
315     );
316
317     my $group1_1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library1->branchcode } } );
318     my $group1_2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library2->branchcode } } );
319
320     my $group2_3 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library3->branchcode } } );
321     my $group2_4 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library4->branchcode } } );
322
323     my $group3_5 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library5->branchcode } } );
324     my $group3_6 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library6->branchcode } } );
325     my $group3_7 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library7->branchcode } } );
326     my $group3_8 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library8->branchcode } } );
327
328     my $biblio1  = $builder->build_sample_biblio({ title => '1' });
329     my $biblio2  = $builder->build_sample_biblio({ title => '2' });
330
331     my $item1_1  = $builder->build_sample_item({
332         biblionumber     => $biblio1->biblionumber,
333         homebranch       => $library1->branchcode,
334         holdingbranch    => $library2->branchcode,
335     })->store;
336
337     my $item1_3  = $builder->build_sample_item({
338         biblionumber     => $biblio1->biblionumber,
339         homebranch       => $library3->branchcode,
340         holdingbranch    => $library4->branchcode,
341     })->store;
342
343     my $item1_7  = $builder->build_sample_item({
344         biblionumber     => $biblio1->biblionumber,
345         homebranch       => $library7->branchcode,
346         holdingbranch    => $library4->branchcode,
347     })->store;
348
349     my $item2_2  = $builder->build_sample_item({
350         biblionumber     => $biblio2->biblionumber,
351         homebranch       => $library2->branchcode,
352         holdingbranch    => $library1->branchcode,
353     })->store;
354
355     my $item2_4  = $builder->build_sample_item({
356         biblionumber     => $biblio2->biblionumber,
357         homebranch       => $library4->branchcode,
358         holdingbranch    => $library3->branchcode,
359     })->store;
360
361     my $item2_6  = $builder->build_sample_item({
362         biblionumber     => $biblio2->biblionumber,
363         homebranch       => $library6->branchcode,
364         holdingbranch    => $library4->branchcode,
365     })->store;
366
367     my $patron1 = $builder->build_object( { class => 'Koha::Patrons', value => { firstname=>'1', branchcode => $library1->branchcode } } );
368     my $patron8 = $builder->build_object( { class => 'Koha::Patrons', value => { firstname=>'8', branchcode => $library8->branchcode } } );
369
370     my $results = {
371         "ItemHomeLibrary-1-1" => 6  + $nb_libraries,
372         "ItemHomeLibrary-1-8" => 1,
373         "ItemHomeLibrary-2-1" => 2,
374         "ItemHomeLibrary-2-8" => 0,
375         "PatronLibrary-1-1" => 6 + $nb_libraries,
376         "PatronLibrary-1-8" => 3,
377         "PatronLibrary-2-1" => 0,
378         "PatronLibrary-2-8" => 3,
379     };
380
381     sub _doTest {
382         my ( $cbranch, $biblio, $patron, $results ) = @_;
383         t::lib::Mocks::mock_preference('ReservesControlBranch', $cbranch);
384
385         my @pl = $biblio->pickup_locations( { patron => $patron } );
386
387         foreach my $pickup_location (@pl) {
388             next
389               unless grep { $pickup_location eq $_ } @branchcodes;
390
391             is( ref($pickup_location), 'Koha::Library', 'Object type is correct' );
392         }
393
394         ok(
395             scalar(@pl) == $results->{ $cbranch . '-'
396                   . $biblio->title . '-'
397                   . $patron->firstname },
398             'ReservesControlBranch: '
399               . $cbranch
400               . ', biblio'
401               . $biblio->title
402               . ', patron'
403               . $patron->firstname
404               . ' should return '
405               . $results->{ $cbranch . '-'
406                   . $biblio->title . '-'
407                   . $patron->firstname }
408               . ' but returns '
409               . scalar(@pl)
410         );
411     }
412
413     foreach my $cbranch ('ItemHomeLibrary','PatronLibrary') {
414         foreach my $biblio ($biblio1, $biblio2) {
415             foreach my $patron ($patron1, $patron8) {
416                 _doTest($cbranch, $biblio, $patron, $results);
417             }
418         }
419     }
420
421     $schema->storage->txn_rollback;
422 };
423
424 subtest 'to_api() tests' => sub {
425
426     $schema->storage->txn_begin;
427
428     my $biblio = $builder->build_sample_biblio();
429     my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
430
431     my $biblioitem_api = $biblio->biblioitem->to_api;
432     my $biblio_api     = $biblio->to_api;
433
434     plan tests => (scalar keys %{ $biblioitem_api }) + 1;
435
436     foreach my $key ( keys %{ $biblioitem_api } ) {
437         is( $biblio_api->{$key}, $biblioitem_api->{$key}, "$key is added to the biblio object" );
438     }
439
440     $biblio_api = $biblio->to_api({ embed => { items => {} } });
441     is_deeply( $biblio_api->{items}, [ $item->to_api ], 'Item correctly embedded' );
442
443     $schema->storage->txn_rollback;
444 };
445
446 subtest 'suggestions() tests' => sub {
447
448     plan tests => 3;
449
450     $schema->storage->txn_begin;
451
452     my $biblio     = $builder->build_sample_biblio();
453
454     is( ref($biblio->suggestions), 'Koha::Suggestions', 'Return type is correct' );
455
456     is_deeply(
457         $biblio->suggestions->unblessed,
458         [],
459         '->suggestions returns an empty Koha::Suggestions resultset'
460     );
461
462     my $suggestion = $builder->build_object(
463         {
464             class => 'Koha::Suggestions',
465             value => { biblionumber => $biblio->biblionumber }
466         }
467     );
468
469     my $suggestions = $biblio->suggestions->unblessed;
470
471     is_deeply(
472         $biblio->suggestions->unblessed,
473         [ $suggestion->unblessed ],
474         '->suggestions returns the related Koha::Suggestion objects'
475     );
476
477     $schema->storage->txn_rollback;
478 };
479
480 subtest 'orders() and active_orders() tests' => sub {
481
482     plan tests => 5;
483
484     $schema->storage->txn_begin;
485
486     my $biblio = $builder->build_sample_biblio();
487
488     my $orders        = $biblio->orders;
489     my $active_orders = $biblio->active_orders;
490
491     is( ref($orders), 'Koha::Acquisition::Orders', 'Result type is correct' );
492     is( $biblio->orders->count, $biblio->active_orders->count, '->orders->count returns the count for the resultset' );
493
494     # Add a couple orders
495     foreach (1..2) {
496         $builder->build_object(
497             {
498                 class => 'Koha::Acquisition::Orders',
499                 value => {
500                     biblionumber => $biblio->biblionumber,
501                     datecancellationprinted => '2019-12-31'
502                 }
503             }
504         );
505     }
506
507     $builder->build_object(
508         {
509             class => 'Koha::Acquisition::Orders',
510             value => {
511                 biblionumber => $biblio->biblionumber,
512                 datecancellationprinted => undef
513             }
514         }
515     );
516
517     $orders = $biblio->orders;
518     $active_orders = $biblio->active_orders;
519
520     is( ref($orders), 'Koha::Acquisition::Orders', 'Result type is correct' );
521     is( ref($active_orders), 'Koha::Acquisition::Orders', 'Result type is correct' );
522     is( $orders->count, $active_orders->count + 2, '->active_orders->count returns the rigt count' );
523
524     $schema->storage->txn_rollback;
525 };
526
527 subtest 'subscriptions() tests' => sub {
528
529     plan tests => 4;
530
531     $schema->storage->txn_begin;
532
533     my $biblio = $builder->build_sample_biblio;
534
535     my $subscriptions = $biblio->subscriptions;
536     is( ref($subscriptions), 'Koha::Subscriptions',
537         'Koha::Biblio->subscriptions should return a Koha::Subscriptions object'
538     );
539     is( $subscriptions->count, 0, 'Koha::Biblio->subscriptions should return the correct number of subscriptions');
540
541     # Add two subscriptions
542     foreach (1..2) {
543         $builder->build_object(
544             {
545                 class => 'Koha::Subscriptions',
546                 value => { biblionumber => $biblio->biblionumber }
547             }
548         );
549     }
550
551     $subscriptions = $biblio->subscriptions;
552     is( ref($subscriptions), 'Koha::Subscriptions',
553         'Koha::Biblio->subscriptions should return a Koha::Subscriptions object'
554     );
555     is( $subscriptions->count, 2, 'Koha::Biblio->subscriptions should return the correct number of subscriptions');
556
557     $schema->storage->txn_rollback;
558 };