Bug 24366: Make sure accessors are used on the right object
[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 => 9;
21
22 use C4::Biblio;
23 use Koha::Database;
24
25 use t::lib::TestBuilder;
26 use t::lib::Mocks;
27
28 BEGIN {
29     use_ok('Koha::Biblio');
30     use_ok('Koha::Biblios');
31 }
32
33 my $schema  = Koha::Database->new->schema;
34 my $builder = t::lib::TestBuilder->new;
35
36 subtest 'metadata() tests' => sub {
37
38     plan tests => 4;
39
40     $schema->storage->txn_begin;
41
42     my $title = 'Oranges and Peaches';
43
44     my $record = MARC::Record->new();
45     my $field = MARC::Field->new('245','','','a' => $title);
46     $record->append_fields( $field );
47     my ($biblionumber) = C4::Biblio::AddBiblio($record, '');
48
49     my $biblio = Koha::Biblios->find( $biblionumber );
50     is( ref $biblio, 'Koha::Biblio', 'Found a Koha::Biblio object' );
51
52     my $metadata = $biblio->metadata;
53     is( ref $metadata, 'Koha::Biblio::Metadata', 'Method metadata() returned a Koha::Biblio::Metadata object' );
54
55     my $record2 = $metadata->record;
56     is( ref $record2, 'MARC::Record', 'Method record() returned a MARC::Record object' );
57
58     is( $record2->field('245')->subfield("a"), $title, 'Title in 245$a matches title from original record object' );
59
60     $schema->storage->txn_rollback;
61 };
62
63 subtest 'hidden_in_opac() tests' => sub {
64
65     plan tests => 4;
66
67     $schema->storage->txn_begin;
68
69     my $biblio = $builder->build_sample_biblio();
70
71     ok( !$biblio->hidden_in_opac({ rules => { withdrawn => [ 2 ] } }), 'Biblio not hidden if there is no item attached' );
72
73     my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
74     my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
75
76     $item_1->withdrawn( 1 )->store->discard_changes;
77     $item_2->withdrawn( 1 )->store->discard_changes;
78
79     ok( !$biblio->hidden_in_opac({ rules => { withdrawn => [ 2 ] } }), 'Biblio not hidden' );
80
81     $item_2->withdrawn( 2 )->store->discard_changes;
82     $biblio->discard_changes; # refresh
83
84     ok( !$biblio->hidden_in_opac({ rules => { withdrawn => [ 2 ] } }), 'Biblio not hidden' );
85
86     $item_1->withdrawn( 2 )->store->discard_changes;
87     $biblio->discard_changes; # refresh
88
89     ok( $biblio->hidden_in_opac({ rules => { withdrawn => [ 2 ] } }), 'Biblio hidden' );
90
91     $schema->storage->txn_rollback;
92 };
93
94 subtest 'items() tests' => sub {
95
96     plan tests => 3;
97
98     $schema->storage->txn_begin;
99
100     my $biblio = $builder->build_sample_biblio();
101     my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
102     my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
103
104     my $items = $biblio->items;
105     is( ref($items), 'Koha::Items', 'Returns a Koha::Items resultset' );
106     is( $items->count, 2, 'Two items in resultset' );
107
108     my @items = $biblio->items->as_list;
109     is( scalar @items, 2, 'Same result, but in list context' );
110
111     $schema->storage->txn_rollback;
112
113 };
114
115 subtest 'get_coins and get_openurl' => sub {
116
117     plan tests => 3;
118
119     $schema->storage->txn_begin;
120
121     my $builder = t::lib::TestBuilder->new;
122     my $biblio = $builder->build_sample_biblio({
123             title => 'Title 1',
124             author => 'Author 1'
125         });
126
127     is(
128         $biblio->get_coins,
129         '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',
130         'GetCOinsBiblio returned right metadata'
131     );
132
133     t::lib::Mocks::mock_preference("OpenURLResolverURL", "https://koha.example.com/");
134     is(
135         $biblio->get_openurl,
136         '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',
137         'Koha::Biblio->get_openurl returned right URL'
138     );
139
140     t::lib::Mocks::mock_preference("OpenURLResolverURL", "https://koha.example.com/?client_id=ci1");
141     is(
142         $biblio->get_openurl,
143         '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',
144         'Koha::Biblio->get_openurl returned right URL'
145     );
146
147     $schema->storage->txn_rollback;
148 };
149
150 subtest 'is_serial() tests' => sub {
151
152     plan tests => 3;
153
154     $schema->storage->txn_begin;
155
156     my $biblio = $builder->build_sample_biblio();
157
158     $biblio->serial( 1 )->store->discard_changes;
159     ok( $biblio->is_serial, 'Bibliographic record is serial' );
160
161     $biblio->serial( 0 )->store->discard_changes;
162     ok( !$biblio->is_serial, 'Bibliographic record is not serial' );
163
164     my $record = $biblio->metadata->record;
165     $record->leader('00142nas a22     7a 4500');
166     ModBiblio($record, $biblio->biblionumber );
167     $biblio = Koha::Biblios->find($biblio->biblionumber);
168
169     ok( $biblio->is_serial, 'Bibliographic record is serial' );
170
171     $schema->storage->txn_rollback;
172 };
173
174 subtest 'pickup_locations' => sub {
175     plan tests => 29;
176
177     $schema->storage->txn_begin;
178
179     my $dbh = C4::Context->dbh;
180
181     # Cleanup database
182     Koha::Holds->search->delete;
183     Koha::Patrons->search->delete;
184     Koha::Items->search->delete;
185     Koha::Libraries->search->delete;
186     $dbh->do('DELETE FROM issues');
187     $dbh->do('DELETE FROM issuingrules');
188     $dbh->do(
189         q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed)
190         VALUES (?, ?, ?, ?)},
191         {},
192         '*', '*', '*', 25
193     );
194     $dbh->do('DELETE FROM circulation_rules');
195
196     my $root1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
197     my $root2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
198     my $root3 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
199
200     my $library1 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
201     my $library2 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
202     my $library3 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 0 } } );
203     my $library4 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
204     my $library5 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
205     my $library6 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
206     my $library7 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
207     my $library8 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 0 } } );
208
209     Koha::CirculationRules->set_rules(
210         {
211             branchcode => $library1->branchcode,
212             itemtype   => undef,
213             categorycode => undef,
214             rules => {
215                 holdallowed => 1,
216                 hold_fulfillment_policy => 'any',
217                 returnbranch => 'any'
218             }
219         }
220     );
221
222     Koha::CirculationRules->set_rules(
223         {
224             branchcode => $library2->branchcode,
225             itemtype   => undef,
226             categorycode => undef,
227             rules => {
228                 holdallowed => 3,
229                 hold_fulfillment_policy => 'holdgroup',
230                 returnbranch => 'any'
231             }
232         }
233     );
234
235     Koha::CirculationRules->set_rules(
236         {
237             branchcode => $library3->branchcode,
238             itemtype   => undef,
239             categorycode => undef,
240             rules => {
241                 holdallowed => 3,
242                 hold_fulfillment_policy => 'patrongroup',
243                 returnbranch => 'any'
244             }
245         }
246     );
247
248     Koha::CirculationRules->set_rules(
249         {
250             branchcode => $library4->branchcode,
251             itemtype   => undef,
252             categorycode => undef,
253             rules => {
254                 holdallowed => 2,
255                 hold_fulfillment_policy => 'holdingbranch',
256                 returnbranch => 'any'
257             }
258         }
259     );
260
261     Koha::CirculationRules->set_rules(
262         {
263             branchcode => $library5->branchcode,
264             itemtype   => undef,
265             categorycode => undef,
266             rules => {
267                 holdallowed => 2,
268                 hold_fulfillment_policy => 'homebranch',
269                 returnbranch => 'any'
270             }
271         }
272     );
273
274     Koha::CirculationRules->set_rules(
275         {
276             branchcode => $library6->branchcode,
277             itemtype   => undef,
278             categorycode => undef,
279             rules => {
280                 holdallowed => 1,
281                 hold_fulfillment_policy => 'holdgroup',
282                 returnbranch => 'any'
283             }
284         }
285     );
286
287     Koha::CirculationRules->set_rules(
288         {
289             branchcode => $library7->branchcode,
290             itemtype   => undef,
291             categorycode => 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             categorycode => undef,
306             rules => {
307                 holdallowed => 2,
308                 hold_fulfillment_policy => 'patrongroup',
309                 returnbranch => 'any'
310             }
311         }
312     );
313
314     my $group1_1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library1->branchcode } } );
315     my $group1_2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library2->branchcode } } );
316
317     my $group2_3 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library3->branchcode } } );
318     my $group2_4 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library4->branchcode } } );
319
320     my $group3_5 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library5->branchcode } } );
321     my $group3_6 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library6->branchcode } } );
322     my $group3_7 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library7->branchcode } } );
323     my $group3_8 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library8->branchcode } } );
324
325     my $biblio1  = $builder->build_object( { class => 'Koha::Biblios', value => {title => '1'} } );
326     my $biblioitem1 = $builder->build_object( { class => 'Koha::Biblioitems', value => { biblionumber => $biblio1->biblionumber } } );
327     my $biblio2  = $builder->build_object( { class => 'Koha::Biblios', value => {title => '2'} } );
328     my $biblioitem2 = $builder->build_object( { class => 'Koha::Biblioitems', value => { biblionumber => $biblio2->biblionumber } } );
329
330     my $item1_1  = Koha::Item->new({
331         biblionumber     => $biblio1->biblionumber,
332         biblioitemnumber => $biblioitem1->biblioitemnumber,
333         homebranch       => $library1->branchcode,
334         holdingbranch    => $library2->branchcode,
335         itype            => 'test',
336         barcode          => "item11barcode",
337     })->store;
338
339     my $item1_3  = Koha::Item->new({
340         biblionumber     => $biblio1->biblionumber,
341         biblioitemnumber => $biblioitem1->biblioitemnumber,
342         homebranch       => $library3->branchcode,
343         holdingbranch    => $library4->branchcode,
344         itype            => 'test',
345         barcode          => "item13barcode",
346     })->store;
347
348     my $item1_7  = Koha::Item->new({
349         biblionumber     => $biblio1->biblionumber,
350         biblioitemnumber => $biblioitem1->biblioitemnumber,
351         homebranch       => $library7->branchcode,
352         holdingbranch    => $library4->branchcode,
353         itype            => 'test',
354         barcode          => "item17barcode",
355     })->store;
356
357     my $item2_2  = Koha::Item->new({
358         biblionumber     => $biblio2->biblionumber,
359         biblioitemnumber => $biblioitem2->biblioitemnumber,
360         homebranch       => $library2->branchcode,
361         holdingbranch    => $library1->branchcode,
362         itype            => 'test',
363         barcode          => "item22barcode",
364     })->store;
365
366     my $item2_4  = Koha::Item->new({
367         biblionumber     => $biblio2->biblionumber,
368         biblioitemnumber => $biblioitem2->biblioitemnumber,
369         homebranch       => $library4->branchcode,
370         holdingbranch    => $library3->branchcode,
371         itype            => 'test',
372         barcode          => "item23barcode",
373     })->store;
374
375     my $item2_6  = Koha::Item->new({
376         biblionumber     => $biblio2->biblionumber,
377         biblioitemnumber => $biblioitem2->biblioitemnumber,
378         homebranch       => $library6->branchcode,
379         holdingbranch    => $library4->branchcode,
380         itype            => 'test',
381         barcode          => "item26barcode",
382     })->store;
383
384     my $patron1 = $builder->build_object( { class => 'Koha::Patrons', value => { firstname=>'1', branchcode => $library1->branchcode } } );
385     my $patron8 = $builder->build_object( { class => 'Koha::Patrons', value => { firstname=>'8', branchcode => $library8->branchcode } } );
386
387     my $results = {
388         "ItemHomeLibrary-1-1" => 6,
389         "ItemHomeLibrary-1-8" => 1,
390         "ItemHomeLibrary-2-1" => 2,
391         "ItemHomeLibrary-2-8" => 0,
392         "PatronLibrary-1-1" => 6,
393         "PatronLibrary-1-8" => 3,
394         "PatronLibrary-2-1" => 0,
395         "PatronLibrary-2-8" => 3,
396     };
397
398     sub _doTest {
399         my ( $cbranch, $biblio, $patron, $results ) = @_;
400         t::lib::Mocks::mock_preference('ReservesControlBranch', $cbranch);
401
402         my @pl = $biblio->pickup_locations( { patron => $patron} );
403
404         foreach my $pickup_location (@pl) {
405             is( ref($pickup_location), 'Koha::Library', 'Object type is correct' );
406         }
407
408         ok(
409             scalar(@pl) == $results->{ $cbranch . '-'
410                   . $biblio->title . '-'
411                   . $patron->firstname },
412             'ReservesControlBranch: '
413               . $cbranch
414               . ', biblio'
415               . $biblio->title
416               . ', patron'
417               . $patron->firstname
418               . ' should return '
419               . $results->{ $cbranch . '-'
420                   . $biblio->title . '-'
421                   . $patron->firstname }
422               . ' but returns '
423               . scalar(@pl)
424         );
425     }
426
427     foreach my $cbranch ('ItemHomeLibrary','PatronLibrary') {
428         foreach my $biblio ($biblio1, $biblio2) {
429             foreach my $patron ($patron1, $patron8) {
430                 _doTest($cbranch, $biblio, $patron, $results);
431             }
432         }
433     }
434
435     $schema->storage->txn_rollback;
436 };
437
438 subtest 'to_api() tests' => sub {
439
440     $schema->storage->txn_begin;
441
442     my $biblio = $builder->build_sample_biblio();
443     my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
444
445     my $biblioitem_api = $biblio->biblioitem->to_api;
446     my $biblio_api     = $biblio->to_api;
447
448     plan tests => (scalar keys %{ $biblioitem_api }) + 1;
449
450     foreach my $key ( keys %{ $biblioitem_api } ) {
451         is( $biblio_api->{$key}, $biblioitem_api->{$key}, "$key is added to the biblio object" );
452     }
453
454     $biblio_api = $biblio->to_api({ embed => { items => {} } });
455     is_deeply( $biblio_api->{items}, [ $item->to_api ], 'Item correctly embedded' );
456
457     $schema->storage->txn_rollback;
458 };