3 # Copyright 2020 Koha Development team
5 # This file is part of Koha
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
22 use Test::More tests => 4;
27 use t::lib::TestBuilder;
33 my $schema = Koha::Database->new->schema;
34 my $builder = t::lib::TestBuilder->new;
36 subtest 'fill() tests' => sub {
40 $schema->storage->txn_begin;
44 my $category = $builder->build_object(
46 class => 'Koha::Patron::Categories',
47 value => { reservefee => $fee }
50 my $patron = $builder->build_object(
52 class => 'Koha::Patrons',
53 value => { categorycode => $category->id }
56 my $manager = $builder->build_object( { class => 'Koha::Patrons' } );
58 my $title = 'Do what you want';
59 my $biblio = $builder->build_sample_biblio( { title => $title } );
60 my $item = $builder->build_sample_item( { biblionumber => $biblio->id } );
61 my $hold = $builder->build_object(
63 class => 'Koha::Holds',
65 biblionumber => $biblio->id,
66 borrowernumber => $patron->id,
67 itemnumber => $item->id,
73 t::lib::Mocks::mock_preference( 'HoldFeeMode', 'any_time_is_collected' );
74 t::lib::Mocks::mock_preference( 'HoldsLog', 1 );
75 t::lib::Mocks::mock_userenv(
76 { patron => $manager, branchcode => $manager->branchcode } );
78 my $interface = 'api';
79 C4::Context->interface($interface);
81 my $ret = $hold->fill;
83 is( ref($ret), 'Koha::Hold', '->fill returns the object type' );
84 is( $ret->id, $hold->id, '->fill returns the object' );
86 is( Koha::Holds->find($hold->id), undef, 'Hold no longer current' );
87 my $old_hold = Koha::Old::Holds->find( $hold->id );
89 is( $old_hold->id, $hold->id, 'reserve_id retained' );
90 is( $old_hold->priority, 0, 'priority set to 0' );
91 is( $old_hold->found, 'F', 'found set to F' );
93 subtest 'fee applied tests' => sub {
97 my $account = $patron->account;
98 is( $account->balance, $fee, 'Charge applied correctly' );
100 my $debits = $account->outstanding_debits;
101 is( $debits->count, 1, 'Only one fee charged' );
103 my $fee_debit = $debits->next;
104 is( $fee_debit->amount * 1, $fee, 'Fee amount stored correctly' );
105 is( $fee_debit->description, $title,
106 'Fee description stored correctly' );
107 is( $fee_debit->manager_id, $manager->id,
108 'Fee manager_id stored correctly' );
109 is( $fee_debit->branchcode, $manager->branchcode,
110 'Fee branchcode stored correctly' );
111 is( $fee_debit->interface, $interface,
112 'Fee interface stored correctly' );
113 is( $fee_debit->debit_type_code,
114 'RESERVE', 'Fee debit_type_code stored correctly' );
115 is( $fee_debit->itemnumber, $item->id,
116 'Fee itemnumber stored correctly' );
119 my $logs = Koha::ActionLogs->search(
127 is( $logs->count, 1, '1 log line added' );
129 # Set HoldFeeMode to something other than any_time_is_collected
130 t::lib::Mocks::mock_preference( 'HoldFeeMode', 'not_always' );
132 t::lib::Mocks::mock_preference( 'HoldsLog', 0 );
134 $hold = $builder->build_object(
136 class => 'Koha::Holds',
138 biblionumber => $biblio->id,
139 borrowernumber => $patron->id,
140 itemnumber => $item->id,
148 my $account = $patron->account;
149 is( $account->balance, $fee, 'No new charge applied' );
151 my $debits = $account->outstanding_debits;
152 is( $debits->count, 1, 'Only one fee charged, because of HoldFeeMode' );
154 $logs = Koha::ActionLogs->search(
162 is( $logs->count, 0, 'HoldsLog disabled, no logs added' );
164 $schema->storage->txn_rollback;
167 subtest 'patron() tests' => sub {
171 $schema->storage->txn_begin;
173 my $patron = $builder->build_object({ class => 'Koha::Patrons' });
174 my $hold = $builder->build_object(
176 class => 'Koha::Holds',
178 borrowernumber => $patron->borrowernumber
183 my $hold_patron = $hold->patron;
184 is( ref($hold_patron), 'Koha::Patron', 'Right type' );
185 is( $hold_patron->id, $patron->id, 'Right object' );
187 $schema->storage->txn_rollback;
190 subtest 'set_pickup_location() tests' => sub {
194 $schema->storage->txn_begin;
196 my $mock_biblio = Test::MockModule->new('Koha::Biblio');
197 my $mock_item = Test::MockModule->new('Koha::Item');
199 my $library_1 = $builder->build_object({ class => 'Koha::Libraries' });
200 my $library_2 = $builder->build_object({ class => 'Koha::Libraries' });
201 my $library_3 = $builder->build_object({ class => 'Koha::Libraries' });
203 # let's control what Koha::Biblio->pickup_locations returns, for testing
204 $mock_biblio->mock( 'pickup_locations', sub {
205 return Koha::Libraries->search( { branchcode => [ $library_2->branchcode, $library_3->branchcode ] } );
207 # let's mock what Koha::Item->pickup_locations returns, for testing
208 $mock_item->mock( 'pickup_locations', sub {
209 return Koha::Libraries->search( { branchcode => [ $library_2->branchcode, $library_3->branchcode ] } );
212 my $biblio = $builder->build_sample_biblio;
213 my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
215 # Test biblio-level holds
216 my $biblio_hold = $builder->build_object(
218 class => "Koha::Holds",
220 biblionumber => $biblio->biblionumber,
221 branchcode => $library_3->branchcode,
228 { $biblio_hold->set_pickup_location({ library_id => $library_1->branchcode }); }
229 'Koha::Exceptions::Hold::InvalidPickupLocation',
230 'Exception thrown on invalid pickup location';
232 $biblio_hold->discard_changes;
233 is( $biblio_hold->branchcode, $library_3->branchcode, 'branchcode remains untouched' );
235 my $ret = $biblio_hold->set_pickup_location({ library_id => $library_2->id });
236 is( ref($ret), 'Koha::Hold', 'self is returned' );
238 $biblio_hold->discard_changes;
239 is( $biblio_hold->branchcode, $library_2->id, 'Pickup location changed correctly' );
241 # Test item-level holds
242 my $item_hold = $builder->build_object(
244 class => "Koha::Holds",
246 biblionumber => $biblio->biblionumber,
247 branchcode => $library_3->branchcode,
248 itemnumber => $item->itemnumber,
254 { $item_hold->set_pickup_location({ library_id => $library_1->branchcode }); }
255 'Koha::Exceptions::Hold::InvalidPickupLocation',
256 'Exception thrown on invalid pickup location';
258 $item_hold->discard_changes;
259 is( $item_hold->branchcode, $library_3->branchcode, 'branchcode remains untouched' );
261 $item_hold->set_pickup_location({ library_id => $library_1->branchcode, force => 1 });
262 $item_hold->discard_changes;
263 is( $item_hold->branchcode, $library_1->branchcode, 'branchcode changed because of \'force\'' );
265 $ret = $item_hold->set_pickup_location({ library_id => $library_2->id });
266 is( ref($ret), 'Koha::Hold', 'self is returned' );
268 $item_hold->discard_changes;
269 is( $item_hold->branchcode, $library_2->id, 'Pickup location changed correctly' );
272 { $item_hold->set_pickup_location({ library_id => undef }); }
273 'Koha::Exceptions::MissingParameter',
274 'Exception thrown if missing parameter';
276 is( "$@", 'The library_id parameter is mandatory', 'Exception message is clear' );
278 $schema->storage->txn_rollback;
281 subtest 'is_pickup_location_valid() tests' => sub {
285 $schema->storage->txn_begin;
287 my $mock_biblio = Test::MockModule->new('Koha::Biblio');
288 my $mock_item = Test::MockModule->new('Koha::Item');
290 my $library_1 = $builder->build_object({ class => 'Koha::Libraries' });
291 my $library_2 = $builder->build_object({ class => 'Koha::Libraries' });
292 my $library_3 = $builder->build_object({ class => 'Koha::Libraries' });
294 # let's control what Koha::Biblio->pickup_locations returns, for testing
295 $mock_biblio->mock( 'pickup_locations', sub {
296 return Koha::Libraries->search( { branchcode => [ $library_2->branchcode, $library_3->branchcode ] } );
298 # let's mock what Koha::Item->pickup_locations returns, for testing
299 $mock_item->mock( 'pickup_locations', sub {
300 return Koha::Libraries->search( { branchcode => [ $library_2->branchcode, $library_3->branchcode ] } );
303 my $biblio = $builder->build_sample_biblio;
304 my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
306 # Test biblio-level holds
307 my $biblio_hold = $builder->build_object(
309 class => "Koha::Holds",
311 biblionumber => $biblio->biblionumber,
312 branchcode => $library_3->branchcode,
318 ok( !$biblio_hold->is_pickup_location_valid({ library_id => $library_1->branchcode }), 'Pickup location invalid');
319 ok( $biblio_hold->is_pickup_location_valid({ library_id => $library_2->id }), 'Pickup location valid');
321 # Test item-level holds
322 my $item_hold = $builder->build_object(
324 class => "Koha::Holds",
326 biblionumber => $biblio->biblionumber,
327 branchcode => $library_3->branchcode,
328 itemnumber => $item->itemnumber,
333 ok( !$item_hold->is_pickup_location_valid({ library_id => $library_1->branchcode }), 'Pickup location invalid');
334 ok( $item_hold->is_pickup_location_valid({ library_id => $library_2->id }), 'Pickup location valid' );
336 subtest 'pickup_locations() returning ->empty' => sub {
340 $schema->storage->txn_begin;
342 my $library = $builder->build_object({ class => 'Koha::Libraries' });
344 my $mock_item = Test::MockModule->new('Koha::Item');
345 $mock_item->mock( 'pickup_locations', sub { return Koha::Libraries->new->empty; } );
347 my $mock_biblio = Test::MockModule->new('Koha::Biblio');
348 $mock_biblio->mock( 'pickup_locations', sub { return Koha::Libraries->new->empty; } );
350 my $item = $builder->build_sample_item();
351 my $biblio = $item->biblio;
353 # Test biblio-level holds
354 my $biblio_hold = $builder->build_object(
356 class => "Koha::Holds",
358 biblionumber => $biblio->biblionumber,
364 ok( !$biblio_hold->is_pickup_location_valid({ library_id => $library->branchcode }), 'Pickup location invalid');
366 # Test item-level holds
367 my $item_hold = $builder->build_object(
369 class => "Koha::Holds",
371 biblionumber => $biblio->biblionumber,
372 itemnumber => $item->itemnumber,
377 ok( !$item_hold->is_pickup_location_valid({ library_id => $library->branchcode }), 'Pickup location invalid');
379 $schema->storage->txn_rollback;
382 $schema->storage->txn_rollback;