Bug 24757: (RM follow-up) Restore test count
[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 => 3;
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
131     is(
132         $biblio->get_coins,
133         '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',
134         'GetCOinsBiblio returned right metadata'
135     );
136
137     t::lib::Mocks::mock_preference("OpenURLResolverURL", "https://koha.example.com/");
138     is(
139         $biblio->get_openurl,
140         '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',
141         'Koha::Biblio->get_openurl returned right URL'
142     );
143
144     t::lib::Mocks::mock_preference("OpenURLResolverURL", "https://koha.example.com/?client_id=ci1");
145     is(
146         $biblio->get_openurl,
147         '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',
148         'Koha::Biblio->get_openurl returned right URL'
149     );
150
151     $schema->storage->txn_rollback;
152 };
153
154 subtest 'is_serial() tests' => sub {
155
156     plan tests => 3;
157
158     $schema->storage->txn_begin;
159
160     my $biblio = $builder->build_sample_biblio();
161
162     $biblio->serial( 1 )->store->discard_changes;
163     ok( $biblio->is_serial, 'Bibliographic record is serial' );
164
165     $biblio->serial( 0 )->store->discard_changes;
166     ok( !$biblio->is_serial, 'Bibliographic record is not serial' );
167
168     my $record = $biblio->metadata->record;
169     $record->leader('00142nas a22     7a 4500');
170     ModBiblio($record, $biblio->biblionumber );
171     $biblio = Koha::Biblios->find($biblio->biblionumber);
172
173     ok( $biblio->is_serial, 'Bibliographic record is serial' );
174
175     $schema->storage->txn_rollback;
176 };
177
178 subtest 'pickup_locations' => sub {
179     plan tests => 29;
180
181     $schema->storage->txn_begin;
182
183     my $dbh = C4::Context->dbh;
184
185     # Cleanup database
186     Koha::Holds->search->delete;
187     Koha::Patrons->search->delete;
188     Koha::Items->search->delete;
189     Koha::Libraries->search->delete;
190     Koha::CirculationRules->search->delete;
191     $dbh->do('DELETE FROM issues');
192     Koha::CirculationRules->set_rules(
193         {
194             categorycode => undef,
195             itemtype     => undef,
196             branchcode   => undef,
197             rules        => {
198                 reservesallowed => 25,
199             }
200         }
201     );
202
203     my $root1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
204     my $root2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
205     my $root3 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
206
207     my $library1 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
208     my $library2 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
209     my $library3 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 0 } } );
210     my $library4 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
211     my $library5 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
212     my $library6 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
213     my $library7 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
214     my $library8 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 0 } } );
215
216     Koha::CirculationRules->set_rules(
217         {
218             branchcode => $library1->branchcode,
219             itemtype   => undef,
220             rules => {
221                 holdallowed => 1,
222                 hold_fulfillment_policy => 'any',
223                 returnbranch => 'any'
224             }
225         }
226     );
227
228     Koha::CirculationRules->set_rules(
229         {
230             branchcode => $library2->branchcode,
231             itemtype   => undef,
232             rules => {
233                 holdallowed => 3,
234                 hold_fulfillment_policy => 'holdgroup',
235                 returnbranch => 'any'
236             }
237         }
238     );
239
240     Koha::CirculationRules->set_rules(
241         {
242             branchcode => $library3->branchcode,
243             itemtype   => undef,
244             rules => {
245                 holdallowed => 3,
246                 hold_fulfillment_policy => 'patrongroup',
247                 returnbranch => 'any'
248             }
249         }
250     );
251
252     Koha::CirculationRules->set_rules(
253         {
254             branchcode => $library4->branchcode,
255             itemtype   => undef,
256             rules => {
257                 holdallowed => 2,
258                 hold_fulfillment_policy => 'holdingbranch',
259                 returnbranch => 'any'
260             }
261         }
262     );
263
264     Koha::CirculationRules->set_rules(
265         {
266             branchcode => $library5->branchcode,
267             itemtype   => undef,
268             rules => {
269                 holdallowed => 2,
270                 hold_fulfillment_policy => 'homebranch',
271                 returnbranch => 'any'
272             }
273         }
274     );
275
276     Koha::CirculationRules->set_rules(
277         {
278             branchcode => $library6->branchcode,
279             itemtype   => undef,
280             rules => {
281                 holdallowed => 1,
282                 hold_fulfillment_policy => 'holdgroup',
283                 returnbranch => 'any'
284             }
285         }
286     );
287
288     Koha::CirculationRules->set_rules(
289         {
290             branchcode => $library7->branchcode,
291             itemtype   => undef,
292             rules => {
293                 holdallowed => 3,
294                 hold_fulfillment_policy => 'holdingbranch',
295                 returnbranch => 'any'
296             }
297         }
298     );
299
300
301     Koha::CirculationRules->set_rules(
302         {
303             branchcode => $library8->branchcode,
304             itemtype   => undef,
305             rules => {
306                 holdallowed => 2,
307                 hold_fulfillment_policy => 'patrongroup',
308                 returnbranch => 'any'
309             }
310         }
311     );
312
313     my $group1_1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library1->branchcode } } );
314     my $group1_2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library2->branchcode } } );
315
316     my $group2_3 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library3->branchcode } } );
317     my $group2_4 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library4->branchcode } } );
318
319     my $group3_5 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library5->branchcode } } );
320     my $group3_6 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library6->branchcode } } );
321     my $group3_7 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library7->branchcode } } );
322     my $group3_8 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library8->branchcode } } );
323
324     my $biblio1  = $builder->build_object( { class => 'Koha::Biblios', value => {title => '1'} } );
325     my $biblioitem1 = $builder->build_object( { class => 'Koha::Biblioitems', value => { biblionumber => $biblio1->biblionumber } } );
326     my $biblio2  = $builder->build_object( { class => 'Koha::Biblios', value => {title => '2'} } );
327     my $biblioitem2 = $builder->build_object( { class => 'Koha::Biblioitems', value => { biblionumber => $biblio2->biblionumber } } );
328
329     my $item1_1  = Koha::Item->new({
330         biblionumber     => $biblio1->biblionumber,
331         biblioitemnumber => $biblioitem1->biblioitemnumber,
332         homebranch       => $library1->branchcode,
333         holdingbranch    => $library2->branchcode,
334         itype            => 'test',
335         barcode          => "item11barcode",
336     })->store;
337
338     my $item1_3  = Koha::Item->new({
339         biblionumber     => $biblio1->biblionumber,
340         biblioitemnumber => $biblioitem1->biblioitemnumber,
341         homebranch       => $library3->branchcode,
342         holdingbranch    => $library4->branchcode,
343         itype            => 'test',
344         barcode          => "item13barcode",
345     })->store;
346
347     my $item1_7  = Koha::Item->new({
348         biblionumber     => $biblio1->biblionumber,
349         biblioitemnumber => $biblioitem1->biblioitemnumber,
350         homebranch       => $library7->branchcode,
351         holdingbranch    => $library4->branchcode,
352         itype            => 'test',
353         barcode          => "item17barcode",
354     })->store;
355
356     my $item2_2  = Koha::Item->new({
357         biblionumber     => $biblio2->biblionumber,
358         biblioitemnumber => $biblioitem2->biblioitemnumber,
359         homebranch       => $library2->branchcode,
360         holdingbranch    => $library1->branchcode,
361         itype            => 'test',
362         barcode          => "item22barcode",
363     })->store;
364
365     my $item2_4  = Koha::Item->new({
366         biblionumber     => $biblio2->biblionumber,
367         biblioitemnumber => $biblioitem2->biblioitemnumber,
368         homebranch       => $library4->branchcode,
369         holdingbranch    => $library3->branchcode,
370         itype            => 'test',
371         barcode          => "item23barcode",
372     })->store;
373
374     my $item2_6  = Koha::Item->new({
375         biblionumber     => $biblio2->biblionumber,
376         biblioitemnumber => $biblioitem2->biblioitemnumber,
377         homebranch       => $library6->branchcode,
378         holdingbranch    => $library4->branchcode,
379         itype            => 'test',
380         barcode          => "item26barcode",
381     })->store;
382
383     my $patron1 = $builder->build_object( { class => 'Koha::Patrons', value => { firstname=>'1', branchcode => $library1->branchcode } } );
384     my $patron8 = $builder->build_object( { class => 'Koha::Patrons', value => { firstname=>'8', branchcode => $library8->branchcode } } );
385
386     my $results = {
387         "ItemHomeLibrary-1-1" => 6,
388         "ItemHomeLibrary-1-8" => 1,
389         "ItemHomeLibrary-2-1" => 2,
390         "ItemHomeLibrary-2-8" => 0,
391         "PatronLibrary-1-1" => 6,
392         "PatronLibrary-1-8" => 3,
393         "PatronLibrary-2-1" => 0,
394         "PatronLibrary-2-8" => 3,
395     };
396
397     sub _doTest {
398         my ( $cbranch, $biblio, $patron, $results ) = @_;
399         t::lib::Mocks::mock_preference('ReservesControlBranch', $cbranch);
400
401         my @pl = $biblio->pickup_locations( { patron => $patron} );
402
403         foreach my $pickup_location (@pl) {
404             is( ref($pickup_location), 'Koha::Library', 'Object type is correct' );
405         }
406
407         ok(
408             scalar(@pl) == $results->{ $cbranch . '-'
409                   . $biblio->title . '-'
410                   . $patron->firstname },
411             'ReservesControlBranch: '
412               . $cbranch
413               . ', biblio'
414               . $biblio->title
415               . ', patron'
416               . $patron->firstname
417               . ' should return '
418               . $results->{ $cbranch . '-'
419                   . $biblio->title . '-'
420                   . $patron->firstname }
421               . ' but returns '
422               . scalar(@pl)
423         );
424     }
425
426     foreach my $cbranch ('ItemHomeLibrary','PatronLibrary') {
427         foreach my $biblio ($biblio1, $biblio2) {
428             foreach my $patron ($patron1, $patron8) {
429                 _doTest($cbranch, $biblio, $patron, $results);
430             }
431         }
432     }
433
434     $schema->storage->txn_rollback;
435 };
436
437 subtest 'to_api() tests' => sub {
438
439     $schema->storage->txn_begin;
440
441     my $biblio = $builder->build_sample_biblio();
442     my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
443
444     my $biblioitem_api = $biblio->biblioitem->to_api;
445     my $biblio_api     = $biblio->to_api;
446
447     plan tests => (scalar keys %{ $biblioitem_api }) + 1;
448
449     foreach my $key ( keys %{ $biblioitem_api } ) {
450         is( $biblio_api->{$key}, $biblioitem_api->{$key}, "$key is added to the biblio object" );
451     }
452
453     $biblio_api = $biblio->to_api({ embed => { items => {} } });
454     is_deeply( $biblio_api->{items}, [ $item->to_api ], 'Item correctly embedded' );
455
456     $schema->storage->txn_rollback;
457 };
458
459 subtest 'suggestions() tests' => sub {
460
461     plan tests => 3;
462
463     $schema->storage->txn_begin;
464
465     my $biblio     = $builder->build_sample_biblio();
466
467     is( ref($biblio->suggestions), 'Koha::Suggestions', 'Return type is correct' );
468
469     is_deeply(
470         $biblio->suggestions->unblessed,
471         [],
472         '->suggestions returns an empty Koha::Suggestions resultset'
473     );
474
475     my $suggestion = $builder->build_object(
476         {
477             class => 'Koha::Suggestions',
478             value => { biblionumber => $biblio->biblionumber }
479         }
480     );
481
482     my $suggestions = $biblio->suggestions->unblessed;
483
484     is_deeply(
485         $biblio->suggestions->unblessed,
486         [ $suggestion->unblessed ],
487         '->suggestions returns the related Koha::Suggestion objects'
488     );
489
490     $schema->storage->txn_rollback;
491 };
492
493 subtest 'orders() and active_orders() tests' => sub {
494
495     plan tests => 5;
496
497     $schema->storage->txn_begin;
498
499     my $biblio = $builder->build_sample_biblio();
500
501     my $orders        = $biblio->orders;
502     my $active_orders = $biblio->active_orders;
503
504     is( ref($orders), 'Koha::Acquisition::Orders', 'Result type is correct' );
505     is( $biblio->orders->count, $biblio->active_orders->count, '->orders->count returns the count for the resultset' );
506
507     # Add a couple orders
508     foreach (1..2) {
509         $builder->build_object(
510             {
511                 class => 'Koha::Acquisition::Orders',
512                 value => {
513                     biblionumber => $biblio->biblionumber,
514                     datecancellationprinted => '2019-12-31'
515                 }
516             }
517         );
518     }
519
520     $builder->build_object(
521         {
522             class => 'Koha::Acquisition::Orders',
523             value => {
524                 biblionumber => $biblio->biblionumber,
525                 datecancellationprinted => undef
526             }
527         }
528     );
529
530     $orders = $biblio->orders;
531     $active_orders = $biblio->active_orders;
532
533     is( ref($orders), 'Koha::Acquisition::Orders', 'Result type is correct' );
534     is( ref($active_orders), 'Koha::Acquisition::Orders', 'Result type is correct' );
535     is( $orders->count, $active_orders->count + 2, '->active_orders->count returns the rigt count' );
536
537     $schema->storage->txn_rollback;
538 };
539
540 subtest 'subscriptions() tests' => sub {
541
542     plan tests => 4;
543
544     $schema->storage->txn_begin;
545
546     my $biblio = $builder->build_sample_biblio;
547
548     my $subscriptions = $biblio->subscriptions;
549     is( ref($subscriptions), 'Koha::Subscriptions',
550         'Koha::Biblio->subscriptions should return a Koha::Subscriptions object'
551     );
552     is( $subscriptions->count, 0, 'Koha::Biblio->subscriptions should return the correct number of subscriptions');
553
554     # Add two subscriptions
555     foreach (1..2) {
556         $builder->build_object(
557             {
558                 class => 'Koha::Subscriptions',
559                 value => { biblionumber => $biblio->biblionumber }
560             }
561         );
562     }
563
564     $subscriptions = $biblio->subscriptions;
565     is( ref($subscriptions), 'Koha::Subscriptions',
566         'Koha::Biblio->subscriptions should return a Koha::Subscriptions object'
567     );
568     is( $subscriptions->count, 2, 'Koha::Biblio->subscriptions should return the correct number of subscriptions');
569
570     $schema->storage->txn_rollback;
571 };