Bug 29495: Add relation tests
[koha.git] / t / db_dependent / Koha / Checkouts / ReturnClaim.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 => 6;
21 use Test::Exception;
22
23 use Koha::Database;
24 use Koha::DateUtils qw( dt_from_string output_pref );
25 use Koha::Checkouts::ReturnClaims;
26
27 use t::lib::TestBuilder;
28
29 my $schema  = Koha::Database->new->schema;
30 my $builder = t::lib::TestBuilder->new;
31
32 subtest "store() tests" => sub {
33
34     plan tests => 13;
35
36     $schema->storage->txn_begin;
37
38     my $librarian = $builder->build_object({ class => 'Koha::Patrons' });
39     my $patron    = $builder->build_object({ class => 'Koha::Patrons' });
40     my $item      = $builder->build_sample_item;
41
42     my $checkout = $builder->build_object(
43         {
44             class => 'Koha::Checkouts',
45             value => {
46                 borrowernumber => $patron->borrowernumber,
47                 itemnumber     => $item->itemnumber,
48                 branchcode     => $patron->branchcode
49             }
50         }
51     );
52
53     throws_ok
54         { Koha::Checkouts::ReturnClaim->new(
55             {
56                 issue_id       => $checkout->id,
57                 itemnumber     => $checkout->itemnumber,
58                 borrowernumber => $checkout->borrowernumber,
59                 notes          => 'Some notes'
60             }
61           )->store }
62         'Koha::Exceptions::Checkouts::ReturnClaims::NoCreatedBy',
63         'Exception thrown if no created_by passed on creation';
64
65     my $old_checkout = $builder->build_object(
66         {
67             class => 'Koha::Old::Checkouts',
68             value => {
69                 borrowernumber => $patron->borrowernumber,
70                 itemnumber     => $item->itemnumber,
71                 branchcode     => $patron->branchcode
72             }
73         }
74     );
75
76     my $nullable_created_by = Koha::Checkouts::ReturnClaim->new(
77         {
78             issue_id       => $old_checkout->id,
79             itemnumber     => $old_checkout->itemnumber,
80             borrowernumber => $old_checkout->borrowernumber,
81             notes          => 'Some notes',
82             created_by     => $librarian->borrowernumber
83         }
84     )->store;
85     is( $nullable_created_by->created_by, $librarian->borrowernumber, 'Claim created with created_by set' );
86     ok( $nullable_created_by->in_storage, 'In storage' );
87
88     $nullable_created_by->created_by(undef)->store();
89     is( $nullable_created_by->created_by, undef, 'Deletion was deleted' );
90     ok( $nullable_created_by->in_storage, 'In storage' );
91     is(
92         ref($nullable_created_by->notes('Some other note')->store),
93         'Koha::Checkouts::ReturnClaim',
94         'Subsequent store succeeds after created_by has been unset'
95     );
96
97     is( Koha::Checkouts::ReturnClaims->search({ issue_id => $checkout->id })->count, 0, 'No claims stored' );
98
99     my $claim = Koha::Checkouts::ReturnClaim->new(
100         {
101             issue_id       => $checkout->id,
102             itemnumber     => $checkout->itemnumber,
103             borrowernumber => $checkout->borrowernumber,
104             notes          => 'Some notes',
105             created_by     => $librarian->borrowernumber
106         }
107     )->store;
108
109     is( ref($claim), 'Koha::Checkouts::ReturnClaim', 'Object type is correct' );
110     is( Koha::Checkouts::ReturnClaims->search( { issue_id => $checkout->id } )->count, 1, 'Claim stored on the DB');
111
112     {   # hide useless warnings
113         local *STDERR;
114         open STDERR, '>', '/dev/null';
115         throws_ok {
116             Koha::Checkouts::ReturnClaim->new(
117                 {
118                     issue_id       => $checkout->id,
119                     itemnumber     => $checkout->itemnumber,
120                     borrowernumber => $checkout->borrowernumber,
121                     notes          => 'Some notes',
122                     created_by     => $librarian->borrowernumber
123                 }
124             )->store;
125         }
126         'Koha::Exceptions::Object::DuplicateID',
127             'An exception is thrown on duplicate issue_id';
128         close STDERR;
129
130         like(
131             $@->duplicate_id,
132             qr/(return_claims\.)?issue_id/,
133             'Exception field is correct'
134         );
135     }
136
137     {    # hide useless warnings
138         local *STDERR;
139         open STDERR, '>', '/dev/null';
140
141         my $another_checkout = $builder->build_object({ class => 'Koha::Checkouts' });
142         my $checkout_id = $another_checkout->id;
143         $another_checkout->delete;
144
145         my $THE_claim;
146
147         throws_ok {
148             $THE_claim = Koha::Checkouts::ReturnClaim->new(
149                 {
150                     issue_id       => $checkout_id,
151                     itemnumber     => $checkout->itemnumber,
152                     borrowernumber => $checkout->borrowernumber,
153                     notes          => 'Some notes',
154                     created_by     => $librarian->borrowernumber
155                 }
156             )->store;
157         }
158         'Koha::Exceptions::Object::FKConstraint',
159           'An exception is thrown on invalid issue_id';
160         close STDERR;
161
162         is( $@->broken_fk, 'issue_id', 'Exception field is correct' );
163     }
164
165     $schema->storage->txn_rollback;
166 };
167
168 subtest "resolve() tests" => sub {
169
170     plan tests => 9;
171
172     $schema->storage->txn_begin;
173
174     my $itemlost  = 1;
175     my $librarian = $builder->build_object({ class => 'Koha::Patrons' });
176     my $patron    = $builder->build_object({ class => 'Koha::Patrons' });
177     my $item      = $builder->build_sample_item({ itemlost => $itemlost });
178
179     my $checkout = $builder->build_object(
180         {
181             class => 'Koha::Checkouts',
182             value => {
183                 borrowernumber => $patron->borrowernumber,
184                 itemnumber     => $item->itemnumber,
185                 branchcode     => $patron->branchcode
186             }
187         }
188     );
189
190     my $claim = Koha::Checkouts::ReturnClaim->new(
191         {
192             issue_id       => $checkout->id,
193             itemnumber     => $checkout->itemnumber,
194             borrowernumber => $checkout->borrowernumber,
195             notes          => 'Some notes',
196             created_by     => $librarian->borrowernumber
197         }
198     )->store;
199
200     throws_ok
201         { $claim->resolve({ resolution => 1 }); }
202         'Koha::Exceptions::MissingParameter',
203         "Not passing 'resolved_by' makes it throw an exception";
204
205     throws_ok
206         { $claim->resolve({ resolved_by => 1 }); }
207         'Koha::Exceptions::MissingParameter',
208         "Not passing 'resolution' makes it throw an exception";
209
210     my $deleted_patron = $builder->build_object({ class => 'Koha::Patrons' });
211     my $deleted_patron_id = $deleted_patron->id;
212     $deleted_patron->delete;
213
214     {   # hide useless warnings
215         local *STDERR;
216         open STDERR, '>', '/dev/null';
217
218         throws_ok
219             { $claim->resolve({ resolution => "X", resolved_by => $deleted_patron_id }) }
220             'Koha::Exceptions::Object::FKConstraint',
221             "Exception thrown on invalid resolver";
222
223         close STDERR;
224     }
225
226     my $today    = dt_from_string;
227     my $tomorrow = dt_from_string->add( days => 1 );
228
229     $claim->resolve(
230         {
231             resolution  => "X",
232             resolved_by => $librarian->id,
233             resolved_on => $tomorrow,
234         }
235     )->discard_changes;
236
237     is( output_pref( { str => $claim->resolved_on } ), output_pref( { dt => $tomorrow } ), 'resolved_on set to the passed param' );
238     is( $claim->updated_by, $librarian->id, 'updated_by set to the passed resolved_by' );
239
240     # Make sure $item is refreshed
241     $item->discard_changes;
242     is( $item->itemlost, $itemlost, 'Item lost status remains unchanged' );
243
244     # New checkout and claim
245     $checkout->delete;
246     $checkout = $builder->build_object(
247         {
248             class => 'Koha::Checkouts',
249             value => {
250                 borrowernumber => $patron->borrowernumber,
251                 itemnumber     => $item->itemnumber,
252                 branchcode     => $patron->branchcode
253             }
254         }
255     );
256
257     $claim = Koha::Checkouts::ReturnClaim->new(
258         {
259             issue_id       => $checkout->id,
260             itemnumber     => $checkout->itemnumber,
261             borrowernumber => $checkout->borrowernumber,
262             notes          => 'Some notes',
263             created_by     => $librarian->borrowernumber
264         }
265     )->store;
266
267     my $new_lost_status = 2;
268
269     $claim->resolve(
270         {
271             resolution      => "X",
272             resolved_by     => $librarian->id,
273             resolved_on     => $tomorrow,
274             new_lost_status => $new_lost_status,
275         }
276     )->discard_changes;
277
278     is( output_pref( { str => $claim->resolved_on } ), output_pref( { dt => $tomorrow } ), 'resolved_on set to the passed param' );
279     is( $claim->updated_by, $librarian->id, 'updated_by set to the passed resolved_by' );
280
281     # Make sure $item is refreshed
282     $item->discard_changes;
283     is( $item->itemlost, $new_lost_status, 'Item lost status is updated' );
284
285     $schema->storage->txn_rollback;
286 };
287
288 subtest 'item() tests' => sub {
289
290     plan tests => 3;
291
292     $schema->storage->txn_begin;
293
294     my $librarian = $builder->build_object({ class => 'Koha::Patrons' });
295     my $patron    = $builder->build_object({ class => 'Koha::Patrons' });
296     my $item      = $builder->build_sample_item;
297     my $checkout = $builder->build_object(
298         {
299             class => 'Koha::Checkouts',
300             value => {
301                 borrowernumber => $patron->borrowernumber,
302                 itemnumber     => $item->itemnumber,
303                 branchcode     => $patron->branchcode
304             }
305         }
306     );
307
308     my $claim = Koha::Checkouts::ReturnClaim->new(
309         {
310             issue_id       => $checkout->id,
311             itemnumber     => $checkout->itemnumber,
312             borrowernumber => $checkout->borrowernumber,
313             notes          => 'Some notes',
314             created_by     => $librarian->borrowernumber
315         }
316     )->store;
317
318     my $return_claim_item = $claim->item;
319     is( ref( $return_claim_item ), 'Koha::Item', 'Koha::Checkouts::ReturnClaim->item should return a Koha::Item' );
320     is( $claim->itemnumber, $return_claim_item->itemnumber, 'Koha::Checkouts::ReturnClaim->item should return the correct item' );
321
322     my $itemnumber = $item->itemnumber;
323     $checkout->delete; # Required to allow deletion of item
324     $item->delete;
325
326     my $claims = Koha::Checkouts::ReturnClaims->search({ itemnumber => $itemnumber });
327     is( $claims->count, 0, 'Koha::Checkouts::ReturnClaim is deleted on item deletion' );
328
329     $schema->storage->txn_rollback;
330 };
331
332 subtest 'patron() tests' => sub {
333
334     plan tests => 3;
335
336     $schema->storage->txn_begin;
337
338     my $librarian = $builder->build_object({ class => 'Koha::Patrons' });
339     my $patron    = $builder->build_object({ class => 'Koha::Patrons' });
340     my $item      = $builder->build_sample_item;
341     my $checkout = $builder->build_object(
342         {
343             class => 'Koha::Checkouts',
344             value => {
345                 borrowernumber => $patron->borrowernumber,
346                 itemnumber     => $item->itemnumber,
347                 branchcode     => $patron->branchcode
348             }
349         }
350     );
351
352     my $claim = Koha::Checkouts::ReturnClaim->new(
353         {
354             issue_id       => $checkout->id,
355             itemnumber     => $checkout->itemnumber,
356             borrowernumber => $checkout->borrowernumber,
357             notes          => 'Some notes',
358             created_by     => $librarian->borrowernumber
359         }
360     )->store;
361
362     my $return_claim_patron = $claim->patron;
363     is( ref( $return_claim_patron ), 'Koha::Patron', 'Koha::Checkouts::ReturnClaim->patron should return a Koha::Patron' );
364     is( $claim->borrowernumber, $return_claim_patron->borrowernumber, 'Koha::Checkouts::ReturnClaim->patron should return the correct borrower' );
365
366     my $borrowernumber = $patron->borrowernumber;
367     $checkout->delete; # Required to allow deletion of patron
368     $patron->delete;
369
370     my $claims = Koha::Checkouts::ReturnClaims->search({ borrowernumber => $borrowernumber });
371     is( $claims->count, 0, 'Koha::Checkouts::ReturnClaim is deleted on borrower deletion' );
372
373     $schema->storage->txn_rollback;
374 };
375
376 subtest 'old_checkout() tests' => sub {
377
378     plan tests => 4;
379
380     $schema->storage->txn_begin;
381
382     my $librarian = $builder->build_object({ class => 'Koha::Patrons' });
383     my $patron    = $builder->build_object({ class => 'Koha::Patrons' });
384     my $item      = $builder->build_sample_item;
385     my $old_checkout = $builder->build_object(
386         {
387             class => 'Koha::Old::Checkouts',
388             value => {
389                 borrowernumber => $patron->borrowernumber,
390                 itemnumber     => $item->itemnumber,
391                 branchcode     => $patron->branchcode
392             }
393         }
394     );
395
396     my $claim = Koha::Checkouts::ReturnClaim->new(
397         {
398             issue_id       => $old_checkout->id,
399             itemnumber     => $old_checkout->itemnumber,
400             borrowernumber => $old_checkout->borrowernumber,
401             notes          => 'Some notes',
402             created_by     => $librarian->borrowernumber
403         }
404     )->store;
405
406     my $return_claim_old_checkout = $claim->old_checkout;
407     is( ref( $return_claim_old_checkout ), 'Koha::Old::Checkout', 'Koha::Checkouts::ReturnClaim->old_checkout should return a Koha::Old::Checkout' );
408     is( $claim->issue_id, $return_claim_old_checkout->issue_id, 'Koha::Checkouts::ReturnClaim->old_checkout should return the correct borrower' );
409
410     my $issue_id = $old_checkout->issue_id;
411     $old_checkout->delete;
412
413     my $claims = Koha::Checkouts::ReturnClaims->search({ issue_id => $issue_id });
414     is( $claims->count, 1, 'Koha::Checkouts::ReturnClaim remains on old_checkout deletion' );
415     # FIXME: Should we actually set null on OldCheckout deletion?
416
417     $claim->issue_id(undef)->store;
418     is( $claim->old_checkout, undef, 'Koha::Checkouts::ReturnClaim->old_checkout should return undef if no old_checkout linked' );
419
420     $schema->storage->txn_rollback;
421 };
422
423 subtest 'checkout() tests' => sub {
424
425     plan tests => 4;
426
427     $schema->storage->txn_begin;
428
429     my $librarian = $builder->build_object({ class => 'Koha::Patrons' });
430     my $patron    = $builder->build_object({ class => 'Koha::Patrons' });
431     my $item      = $builder->build_sample_item;
432     my $checkout = $builder->build_object(
433         {
434             class => 'Koha::Checkouts',
435             value => {
436                 borrowernumber => $patron->borrowernumber,
437                 itemnumber     => $item->itemnumber,
438                 branchcode     => $patron->branchcode
439             }
440         }
441     );
442
443     my $claim = Koha::Checkouts::ReturnClaim->new(
444         {
445             issue_id       => $checkout->id,
446             itemnumber     => $checkout->itemnumber,
447             borrowernumber => $checkout->borrowernumber,
448             notes          => 'Some notes',
449             created_by     => $librarian->borrowernumber
450         }
451     )->store;
452
453     my $return_claim_checkout = $claim->checkout;
454     is( ref( $return_claim_checkout ), 'Koha::Checkout', 'Koha::Checkouts::ReturnClaim->checkout should return a Koha::Checkout' );
455     is( $claim->issue_id, $return_claim_checkout->issue_id, 'Koha::Checkouts::ReturnClaim->checkout should return the correct borrower' );
456
457     my $issue_id = $checkout->issue_id;
458     $checkout->delete;
459
460     my $claims = Koha::Checkouts::ReturnClaims->search({ issue_id => $issue_id });
461     is( $claims->count, 1, 'Koha::Checkouts::ReturnClaim remains on checkout deletion' );
462
463     $claim->issue_id(undef)->store;
464     is( $claim->checkout, undef, 'Koha::Checkouts::ReturnClaim->checkout should return undef if no checkout linked' );
465
466     $schema->storage->txn_rollback;
467 };