3 # This file is part of Koha.
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.
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.
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>.
20 use File::Basename qw/basename/;
22 use C4::Circulation qw( AddIssue AddReturn );
25 use Koha::Illrequestattributes;
26 use Koha::Illrequest::Config;
32 use Koha::MessageAttributes;
33 use Koha::Notice::Templates;
34 use Koha::AuthorisedValueCategories;
35 use Koha::AuthorisedValues;
37 use t::lib::TestBuilder;
41 use Test::Deep qw/ cmp_deeply ignore /;
44 use Test::More tests => 15;
46 my $schema = Koha::Database->new->schema;
47 my $builder = t::lib::TestBuilder->new;
48 use_ok('Koha::Illrequest');
49 use_ok('Koha::Illrequests');
51 subtest 'Basic object tests' => sub {
55 $schema->storage->txn_begin;
57 Koha::Illrequests->search->delete;
58 my $illrq = $builder->build({ source => 'Illrequest' });
59 my $illrq_obj = Koha::Illrequests->find($illrq->{illrequest_id});
61 isa_ok($illrq_obj, 'Koha::Illrequest',
62 "Correctly create and load an illrequest object.");
63 isa_ok($illrq_obj->_config, 'Koha::Illrequest::Config',
64 "Created a config object as part of Illrequest creation.");
66 is($illrq_obj->illrequest_id, $illrq->{illrequest_id},
67 "Illrequest_id getter works.");
68 is($illrq_obj->borrowernumber, $illrq->{borrowernumber},
69 "Borrowernumber getter works.");
70 is($illrq_obj->biblio_id, $illrq->{biblio_id},
71 "Biblio_Id getter works.");
72 is($illrq_obj->branchcode, $illrq->{branchcode},
73 "Branchcode getter works.");
74 is($illrq_obj->status, $illrq->{status},
75 "Status getter works.");
76 is($illrq_obj->placed, $illrq->{placed},
77 "Placed getter works.");
78 is($illrq_obj->replied, $illrq->{replied},
79 "Replied getter works.");
80 is($illrq_obj->updated, $illrq->{updated},
81 "Updated getter works.");
82 is($illrq_obj->completed, $illrq->{completed},
83 "Completed getter works.");
84 is($illrq_obj->medium, $illrq->{medium},
85 "Medium getter works.");
86 is($illrq_obj->accessurl, $illrq->{accessurl},
87 "Accessurl getter works.");
88 is($illrq_obj->cost, $illrq->{cost},
89 "Cost getter works.");
90 is($illrq_obj->price_paid, $illrq->{price_paid},
91 "Price_paid getter works.");
92 is($illrq_obj->notesopac, $illrq->{notesopac},
93 "Notesopac getter works.");
94 is($illrq_obj->notesstaff, $illrq->{notesstaff},
95 "Notesstaff getter works.");
96 is($illrq_obj->orderid, $illrq->{orderid},
97 "Orderid getter works.");
98 is($illrq_obj->backend, $illrq->{backend},
99 "Backend getter works.");
101 is($illrq_obj->get_type, undef,
102 'get_type() returns undef if no type is set');
104 source => 'Illrequestattribute',
106 illrequest_id => $illrq_obj->illrequest_id,
111 is($illrq_obj->get_type, 'book',
112 'get_type() returns correct type if set');
114 isnt($illrq_obj->status, 'COMP',
115 "ILL is not currently marked complete.");
116 $illrq_obj->mark_completed;
117 is($illrq_obj->status, 'COMP',
118 "ILL is now marked complete.");
122 is(Koha::Illrequests->search->count, 0,
123 "No illrequest found after delete.");
125 $schema->storage->txn_rollback;
128 subtest 'store borrowernumber change also updates holds' => sub {
131 $schema->storage->txn_begin;
133 Koha::Illrequests->search->delete;
135 my $patron = $builder->build_object({ class => 'Koha::Patrons' });
136 my $other_patron = $builder->build_object({ class => 'Koha::Patrons' });
137 my $biblio = $builder->build_object({ class => 'Koha::Biblios' });
139 my $request = $builder->build_object({
140 class => 'Koha::Illrequests',
142 borrowernumber => $patron->borrowernumber,
143 biblio_id => $biblio->biblionumber,
149 borrowernumber => $patron->borrowernumber,
150 biblionumber => $request->biblio_id
154 my $hold = Koha::Holds->find({
155 biblionumber => $request->biblio_id,
156 borrowernumber => $request->borrowernumber,
159 is( $hold->borrowernumber, $request->borrowernumber,
160 'before change, original borrowernumber found' );
162 $request->borrowernumber( $other_patron->borrowernumber )->store;
165 $hold->discard_changes;
167 is( $hold->borrowernumber, $other_patron->borrowernumber,
168 'after change, changed borrowernumber found in holds' );
170 is( $request->borrowernumber, $other_patron->borrowernumber,
171 'after change, changed borrowernumber found in illrequests' );
173 my $new_request = Koha::Illrequest->new({
174 biblio_id => $biblio->biblionumber,
175 branchcode => $patron->branchcode,
176 })->borrowernumber( $patron->borrowernumber )->store;
178 is( $new_request->borrowernumber, $patron->borrowernumber,
179 'Koha::Illrequest->new()->store() works as expected');
181 my $new_holds_found = Koha::Holds->search({
182 biblionumber => $new_request->biblio_id,
183 borrowernumber => $new_request->borrowernumber,
186 is( $new_holds_found, 0, 'no holds found with new()->store()' );
188 $schema->storage->txn_rollback;
192 subtest 'Working with related objects' => sub {
196 $schema->storage->txn_begin;
198 Koha::Illrequests->search->delete;
200 my $patron = $builder->build({ source => 'Borrower' });
201 my $illrq = $builder->build({
202 source => 'Illrequest',
203 value => { borrowernumber => $patron->{borrowernumber} }
205 my $illrq_obj = Koha::Illrequests->find($illrq->{illrequest_id});
207 isa_ok($illrq_obj->patron, 'Koha::Patron',
208 "OK accessing related patron.");
211 source => 'Illrequestattribute',
212 value => { illrequest_id => $illrq_obj->illrequest_id, type => 'X' }
215 source => 'Illrequestattribute',
216 value => { illrequest_id => $illrq_obj->illrequest_id, type => 'Y' }
219 source => 'Illrequestattribute',
220 value => { illrequest_id => $illrq_obj->illrequest_id, type => 'Z' }
223 is($illrq_obj->illrequestattributes->count, Koha::Illrequestattributes->search->count,
224 "Fetching expected number of Illrequestattributes for our request.");
226 my $illrq1 = $builder->build({ source => 'Illrequest' });
228 source => 'Illrequestattribute',
229 value => { illrequest_id => $illrq1->{illrequest_id}, type => 'X' }
232 is($illrq_obj->illrequestattributes->count + 1, Koha::Illrequestattributes->search->count,
233 "Fetching expected number of Illrequestattributes for our request.");
235 is($illrq_obj->biblio, undef, "->biblio returns undef if no biblio");
236 my $biblio = $builder->build_object({ class => 'Koha::Biblios' });
237 my $req_bib = $builder->build_object({
238 class => 'Koha::Illrequests',
240 biblio_id => $biblio->biblionumber
243 isa_ok($req_bib->biblio, 'Koha::Biblio', "OK accessing related biblio");
246 is(Koha::Illrequestattributes->search->count, 1,
247 "Correct number of illrequestattributes after delete.");
249 isa_ok(Koha::Patrons->find($patron->{borrowernumber}), 'Koha::Patron',
250 "Borrower was not deleted after illrq delete.");
252 $schema->storage->txn_rollback;
255 subtest 'Status Graph tests' => sub {
259 $schema->storage->txn_begin;
261 my $illrq = $builder->build({source => 'Illrequest'});
262 my $illrq_obj = Koha::Illrequests->find($illrq->{illrequest_id});
264 # _core_status_graph tests: it's just a constant, so here we just make
265 # sure it returns a hashref.
266 is(ref $illrq_obj->_core_status_graph, "HASH",
267 "_core_status_graph returns a hash.");
269 # _status_graph_union: let's try different merge operations.
272 $illrq_obj->_status_graph_union($illrq_obj->_core_status_graph, {}),
273 $illrq_obj->_core_status_graph,
274 "core_status_graph + null = core_status_graph"
279 $illrq_obj->_status_graph_union({}, $illrq_obj->_core_status_graph),
280 $illrq_obj->_core_status_graph,
281 "null + core_status_graph = core_status_graph"
284 # Correct merge behaviour
286 $illrq_obj->_status_graph_union({
294 prev_actions => [ 'REQ' ],
296 next_actions => [ 'REQ' ],
301 prev_actions => [ 'QER' ],
303 next_actions => [ 'QER' ],
306 prev_actions => [ 'REQ' ],
308 next_actions => [ 'REQ' ],
311 "REQ atom + linking QER = cyclical status graph"
314 # Create a new node, with no prev_actions and no next_actions. This should
315 # protect us against regressions related to bug 22280.
323 # Add the new node to the core_status_grpah
324 my $new_graph = $illrq_obj->_status_graph_union( $new_node, $illrq_obj->_core_status_graph);
325 # Compare the updated graph to the expected graph
326 # The structure we compare against here is just a copy of the structure found
327 # in Koha::Illrequest::_core_status_graph() + the new node we created above
328 cmp_deeply( $new_graph,
336 prev_actions => [ ], # Actions containing buttons
337 # leading to this status
338 id => 'NEW', # ID of this status
339 name => 'New request', # UI name of this status
340 ui_method_name => 'New request', # UI name of method leading
342 method => 'create', # method to this status
343 next_actions => [ 'REQ', 'GENREQ', 'KILL' ], # buttons to add to all
344 # requests with this status
345 ui_method_icon => 'fa-plus', # UI Style class
348 prev_actions => [ 'NEW', 'REQREV', 'QUEUED', 'CANCREQ' ],
351 ui_method_name => 'Confirm request',
353 next_actions => [ 'REQREV', 'COMP', 'CHK' ],
354 ui_method_icon => 'fa-check',
357 prev_actions => [ 'NEW', 'REQREV' ],
359 name => 'Requested from partners',
360 ui_method_name => 'Place request with partners',
361 method => 'generic_confirm',
362 next_actions => [ 'COMP', 'CHK' ],
363 ui_method_icon => 'fa-send-o',
366 prev_actions => [ 'REQ' ],
368 name => 'Request reverted',
369 ui_method_name => 'Revert Request',
371 next_actions => [ 'REQ', 'GENREQ', 'KILL' ],
372 ui_method_icon => 'fa-times',
377 name => 'Queued request',
380 next_actions => [ 'REQ', 'KILL' ],
384 prev_actions => [ 'NEW' ],
386 name => 'Cancellation requested',
389 next_actions => [ 'KILL', 'REQ' ],
393 prev_actions => [ 'REQ' ],
396 ui_method_name => 'Mark completed',
397 method => 'mark_completed',
398 next_actions => [ 'CHK' ],
399 ui_method_icon => 'fa-check',
402 prev_actions => [ 'QUEUED', 'REQREV', 'NEW', 'CANCREQ' ],
405 ui_method_name => 'Delete request',
408 ui_method_icon => 'fa-trash',
411 prev_actions => [ 'REQ', 'GENREQ', 'COMP' ],
413 name => 'Checked out',
414 ui_method_name => 'Check out',
415 needs_prefs => [ 'CirculateILL' ],
416 needs_perms => [ 'user_circulate_circulate_remaining_permissions' ],
417 needs_all => ignore(),
418 method => 'check_out',
420 ui_method_icon => 'fa-upload',
423 prev_actions => [ 'CHK' ],
425 name => 'Returned to library',
426 ui_method_name => 'Check in',
427 method => 'check_in',
428 next_actions => [ 'COMP' ],
429 ui_method_icon => 'fa-download',
432 "new node + core_status_graph = bigger status graph"
433 ) || diag explain $new_graph;
435 # Create a duplicate node
438 prev_actions => [ 'NEW', 'REQREV', 'QUEUED', 'CANCREQ' ],
441 ui_method_name => 'Confirm request dupe',
443 next_actions => [ 'REQREV', 'COMP', 'CHK' ],
444 ui_method_icon => 'fa-check',
447 # Add the dupe node to the core_status_grpah
448 my $dupe_graph = $illrq_obj->_status_graph_union( $illrq_obj->_core_status_graph, $dupe_node);
449 # Compare the updated graph to the expected graph
450 # The structure we compare against here is just a copy of the structure found
451 # in Koha::Illrequest::_core_status_graph() + the new node we created above
452 cmp_deeply( $dupe_graph,
455 prev_actions => [ ], # Actions containing buttons
456 # leading to this status
457 id => 'NEW', # ID of this status
458 name => 'New request', # UI name of this status
459 ui_method_name => 'New request', # UI name of method leading
461 method => 'create', # method to this status
462 next_actions => [ 'REQ', 'GENREQ', 'KILL' ], # buttons to add to all
463 # requests with this status
464 ui_method_icon => 'fa-plus', # UI Style class
467 prev_actions => [ 'NEW', 'REQREV', 'QUEUED', 'CANCREQ' ],
470 ui_method_name => 'Confirm request dupe',
472 next_actions => [ 'REQREV', 'COMP', 'CHK' ],
473 ui_method_icon => 'fa-check',
476 prev_actions => [ 'NEW', 'REQREV' ],
478 name => 'Requested from partners',
479 ui_method_name => 'Place request with partners',
480 method => 'generic_confirm',
481 next_actions => [ 'COMP', 'CHK' ],
482 ui_method_icon => 'fa-send-o',
485 prev_actions => [ 'REQ' ],
487 name => 'Request reverted',
488 ui_method_name => 'Revert Request',
490 next_actions => [ 'REQ', 'GENREQ', 'KILL' ],
491 ui_method_icon => 'fa-times',
496 name => 'Queued request',
499 next_actions => [ 'REQ', 'KILL' ],
503 prev_actions => [ 'NEW' ],
505 name => 'Cancellation requested',
508 next_actions => [ 'KILL', 'REQ' ],
512 prev_actions => [ 'REQ' ],
515 ui_method_name => 'Mark completed',
516 method => 'mark_completed',
517 next_actions => [ 'CHK' ],
518 ui_method_icon => 'fa-check',
521 prev_actions => [ 'QUEUED', 'REQREV', 'NEW', 'CANCREQ' ],
524 ui_method_name => 'Delete request',
527 ui_method_icon => 'fa-trash',
530 prev_actions => [ 'REQ', 'GENREQ', 'COMP' ],
532 name => 'Checked out',
533 ui_method_name => 'Check out',
534 needs_prefs => [ 'CirculateILL' ],
535 needs_perms => [ 'user_circulate_circulate_remaining_permissions' ],
536 needs_all => ignore(),
537 method => 'check_out',
539 ui_method_icon => 'fa-upload',
542 prev_actions => [ 'CHK' ],
544 name => 'Returned to library',
545 ui_method_name => 'Check in',
546 method => 'check_in',
547 next_actions => [ 'COMP' ],
548 ui_method_icon => 'fa-download',
551 "new node + core_status_graph = bigger status graph"
552 ) || diag explain $dupe_graph;
554 $schema->storage->txn_rollback;
557 subtest 'Backend testing (mocks)' => sub {
561 $schema->storage->txn_begin;
563 # testing load_backend & available_backends requires that we have at least
564 # the Dummy plugin installed. load_backend & available_backends don't
565 # currently have tests as a result.
567 t::lib::Mocks->mock_config('interlibrary_loans', { backend_dir => 'a_dir' } );
568 my $backend = Test::MockObject->new;
569 $backend->set_isa('Koha::Illbackends::Mock');
570 $backend->set_always('name', 'Mock');
572 my $patron = $builder->build({ source => 'Borrower' });
573 my $illrq = $builder->build_object({
574 class => 'Koha::Illrequests',
577 $illrq->_backend($backend);
579 isa_ok($illrq->_backend, 'Koha::Illbackends::Mock',
580 "OK accessing mocked backend.");
582 # _backend_capability tests:
583 # We need to test whether this optional feature of a mocked backend
584 # behaves as expected.
585 # 3 scenarios: feature not implemented, feature implemented, but requested
586 # capability is not provided by backend, & feature is implemented &
587 # capability exists. This method can be used to implement custom backend
588 # functionality, such as unmediated in the BLDSS backend (also see
590 $backend->set_always('capabilities', undef);
591 is($illrq->_backend_capability('Test'), 0,
592 "0 returned on Mock not implementing capabilities.");
594 $backend->set_always('capabilities', 0);
595 is($illrq->_backend_capability('Test'), 0,
596 "0 returned on Mock not implementing Test capability.");
598 $backend->set_always('capabilities', sub { return 'bar'; } );
599 is($illrq->_backend_capability('Test'), 'bar',
600 "'bar' returned on Mock implementing Test capability.");
602 # metadata test: we need to be sure that we return the arbitrary values
607 my ( $self, $rq ) = @_;
609 ID => $rq->illrequest_id,
610 Title => $rq->patron->borrowernumber
618 ID => $illrq->illrequest_id,
619 Title => $illrq->patron->borrowernumber
626 # No backend graph extension
627 $backend->set_always('status_graph', {});
628 is_deeply($illrq->capabilities('COMP'),
630 prev_actions => [ 'REQ' ],
633 ui_method_name => 'Mark completed',
634 method => 'mark_completed',
635 next_actions => [ 'CHK' ],
636 ui_method_icon => 'fa-check',
638 "Dummy status graph for COMP.");
639 is($illrq->capabilities('UNKNOWN'), undef,
640 "Dummy status graph for UNKNOWN.");
641 is_deeply($illrq->capabilities(),
642 $illrq->_core_status_graph,
643 "Dummy full status graph.");
644 # Simple backend graph extension
645 $backend->set_always('status_graph',
648 prev_actions => [ 'REQ' ],
650 next_actions => [ 'REQ' ],
653 is_deeply($illrq->capabilities('QER'),
655 prev_actions => [ 'REQ' ],
657 next_actions => [ 'REQ' ],
659 "Simple status graph for QER.");
660 is($illrq->capabilities('UNKNOWN'), undef,
661 "Simple status graph for UNKNOWN.");
662 is_deeply($illrq->capabilities(),
663 $illrq->_status_graph_union(
664 $illrq->_core_status_graph,
667 prev_actions => [ 'REQ' ],
669 next_actions => [ 'REQ' ],
673 "Simple full status graph.");
677 # No backend graph extension
678 $backend->set_always('status_graph', {});
679 is($illrq->custom_capability('unknown', {}), 0,
680 "Unknown candidate.");
682 # Simple backend graph extension
683 $backend->set_always('status_graph',
686 prev_actions => [ 'REQ' ],
688 method => 'identity',
689 next_actions => [ 'REQ' ],
692 $backend->mock('identity',
693 sub { my ( $self, $params ) = @_; return $params->{other}; });
694 is($illrq->custom_capability('identity', { test => 1, method => 'blah' })->{test}, 1,
695 "Resolve identity custom_capability");
697 $schema->storage->txn_rollback;
701 subtest 'Backend core methods' => sub {
705 $schema->storage->txn_begin;
707 # Build infrastructure
708 my $backend = Test::MockObject->new;
709 $backend->set_isa('Koha::Illbackends::Mock');
710 $backend->set_always('name', 'Mock');
711 $backend->mock('capabilities', sub { return 'Mock'; });
713 my $config = Test::MockObject->new;
714 $config->set_always('backend_dir', "/tmp");
715 $config->set_always('getLimitRules',
716 { default => { count => 0, method => 'active' } });
718 my $illrq = $builder->build_object({
719 class => 'Koha::Illrequests',
720 value => { backend => undef }
722 $illrq->_config($config);
724 # Test error conditions (no backend)
725 throws_ok { $illrq->load_backend; }
726 'Koha::Exceptions::Ill::InvalidBackendId',
727 'Exception raised correctly';
729 throws_ok { $illrq->load_backend(''); }
730 'Koha::Exceptions::Ill::InvalidBackendId',
731 'Exception raised correctly';
733 # Now load the mocked backend
734 $illrq->_backend($backend);
737 is_deeply($illrq->expandTemplate({ test => 1, method => "bar" }),
741 template => "/tmp/Mock/intra-includes/bar.inc",
742 opac_template => "/tmp/Mock/opac-includes/bar.inc",
747 # we are testing simple cases.
748 $backend->set_series('create',
749 { stage => 'bar', method => 'create' },
750 { stage => 'commit', method => 'create' },
751 { stage => 'commit', method => 'create' },
752 { stage => 'commit', method => 'create' },
753 { stage => 'commit', method => 'create' });
755 is_deeply($illrq->backend_create({test => 1}),
757 stage => 'bar', method => 'create',
758 template => "/tmp/Mock/intra-includes/create.inc",
759 opac_template => "/tmp/Mock/opac-includes/create.inc",
761 "Backend create: arbitrary stage.");
763 is_deeply($illrq->backend_create({test => 1}),
765 stage => 'commit', method => 'create', permitted => 0,
766 template => "/tmp/Mock/intra-includes/create.inc",
767 opac_template => "/tmp/Mock/opac-includes/create.inc",
769 "Backend create: arbitrary stage, not permitted.");
770 is($illrq->status, "QUEUED", "Backend create: queued if restricted.");
771 $config->set_always('getLimitRules', {});
772 $illrq->status('NEW');
773 is_deeply($illrq->backend_create({test => 1}),
775 stage => 'commit', method => 'create', permitted => 1,
776 template => "/tmp/Mock/intra-includes/create.inc",
777 opac_template => "/tmp/Mock/opac-includes/create.inc",
779 "Backend create: arbitrary stage, permitted.");
780 is($illrq->status, "NEW", "Backend create: not-queued.");
782 # Test that enabling the unmediated workflow causes the backend's
783 # 'unmediated_ill' method to be called
784 t::lib::Mocks::mock_preference('ILLModuleUnmediated', '1');
788 my ($self, $name) = @_;
789 if ($name eq 'unmediated_ill') {
791 return { unmediated_ill => 1 };
796 $illrq->status('NEW');
798 $illrq->backend_create({test => 1}),
800 'opac_template' => '/tmp/Mock/opac-includes/.inc',
801 'template' => '/tmp/Mock/intra-includes/.inc',
802 'unmediated_ill' => 1
804 "Backend create: commit stage, permitted, ILLModuleUnmediated enabled."
807 # Test that disabling the unmediated workflow causes the backend's
808 # 'unmediated_ill' method to be NOT called
809 t::lib::Mocks::mock_preference('ILLModuleUnmediated', '0');
810 $illrq->status('NEW');
812 $illrq->backend_create({test => 1}),
814 stage => 'commit', method => 'create', permitted => 1,
815 template => "/tmp/Mock/intra-includes/create.inc",
816 opac_template => "/tmp/Mock/opac-includes/create.inc",
818 "Backend create: commit stage, permitted, ILLModuleUnmediated disabled."
822 $backend->set_series('renew', { stage => 'bar', method => 'renew' });
823 is_deeply($illrq->backend_renew({test => 1}),
825 stage => 'bar', method => 'renew',
826 template => "/tmp/Mock/intra-includes/renew.inc",
827 opac_template => "/tmp/Mock/opac-includes/renew.inc",
829 "Backend renew: arbitrary stage.");
832 $backend->set_series('cancel', { stage => 'bar', method => 'cancel' });
833 is_deeply($illrq->backend_cancel({test => 1}),
835 stage => 'bar', method => 'cancel',
836 template => "/tmp/Mock/intra-includes/cancel.inc",
837 opac_template => "/tmp/Mock/opac-includes/cancel.inc",
839 "Backend cancel: arbitrary stage.");
842 $backend->set_series('illview', { stage => '', method => 'illview' });
843 is_deeply($illrq->backend_illview({test => 1}), 0,
844 "Backend illview optional method.");
846 # backend_update_status
847 $backend->set_series('update_status', { stage => 'bar', method => 'update_status' });
848 is_deeply($illrq->backend_update_status({test => 1}),
850 stage => 'bar', method => 'update_status',
851 template => "/tmp/Mock/intra-includes/update_status.inc",
852 opac_template => "/tmp/Mock/opac-includes/update_status.inc",
854 "Backend update_status: arbitrary stage.");
857 $backend->set_series('confirm', { stage => 'bar', method => 'confirm' });
858 is_deeply($illrq->backend_confirm({test => 1}),
860 stage => 'bar', method => 'confirm',
861 template => "/tmp/Mock/intra-includes/confirm.inc",
862 opac_template => "/tmp/Mock/opac-includes/confirm.inc",
864 "Backend confirm: arbitrary stage.");
868 'get_supplier_update',
870 my ( $self, $options ) = @_;
874 $backend->mock('capabilities', sub { return sub { return 1; } });
875 is_deeply($illrq->backend_get_update({}), 1,
876 "Backend get_update method.");
878 $config->set_always('partner_code', "ILLTSTLIB");
879 $backend->set_always('metadata', { Test => "Foobar" });
880 my $illbrn = $builder->build({
882 value => { branchemail => "", branchreplyto => "" }
884 my $partner1 = $builder->build({
885 source => 'Borrower',
886 value => { categorycode => "ILLTSTLIB" },
888 my $partner2 = $builder->build({
889 source => 'Borrower',
890 value => { categorycode => "ILLTSTLIB" },
892 my $gen_conf = $illrq->generic_confirm({
893 current_branchcode => $illbrn->{branchcode}
895 isnt(index($gen_conf->{value}->{draft}->{body}, $backend->metadata->{Test}), -1,
896 "Generic confirm: draft contains metadata."
898 is($gen_conf->{value}->{partners}->next->borrowernumber, $partner1->{borrowernumber},
899 "Generic cofnirm: partner 1 is correct."
901 is($gen_conf->{value}->{partners}->next->borrowernumber, $partner2->{borrowernumber},
902 "Generic confirm: partner 2 is correct."
905 dies_ok { $illrq->generic_confirm({
906 current_branchcode => $illbrn->{branchcode},
909 "Generic confirm: missing to dies OK.";
911 $schema->storage->txn_rollback;
915 subtest 'Helpers' => sub {
919 $schema->storage->txn_begin;
921 # Build infrastructure
922 my $backend = Test::MockObject->new;
923 $backend->set_isa('Koha::Illbackends::Mock');
924 $backend->set_always('name', 'Mock');
928 my ( $self, $rq ) = @_;
936 my $config = Test::MockObject->new;
937 $config->set_always('backend_dir', "/tmp");
939 my $patron = $builder->build({
940 source => 'Borrower',
941 value => { categorycode => "A" }
943 # Create a mocked branch with no email addressed defined
944 my $illbrn = $builder->build({
949 branchillemail => "",
953 my $illrq = $builder->build({
954 source => 'Illrequest',
955 value => { branchcode => "HDE", borrowernumber => $patron->{borrowernumber} }
957 my $illrq_obj = Koha::Illrequests->find($illrq->{illrequest_id});
958 $illrq_obj->_config($config);
959 $illrq_obj->_backend($backend);
962 my $type = 'test_type_1';
963 my $name = 'test_name_1';
964 my $update = Test::MockObject->new;
965 $update->set_isa('Koha::Illrequest::SupplierUpdate');
966 $update->{source_type} = $type;
967 $update->{source_name} = $name;
968 $update->{processors} = [];
969 $update->mock('attach_processor', sub {
970 my ( $self, $to_attach ) = @_;
971 push @{$self->{processors}}, $to_attach;
973 my $processor = Test::MockObject->new;
974 $processor->{target_source_type} = $type;
975 $processor->{target_source_name} = $name;
976 $illrq_obj->init_processors();
977 $illrq_obj->push_processor($processor);
978 $illrq_obj->attach_processors($update);
980 scalar @{$update->{processors}},
982 'attaching processors as appropriate works'
986 $config->set_series('getPrefixes',
987 { HDE => "TEST", TSL => "BAR", default => "DEFAULT" },
988 { A => "ATEST", C => "CBAR", default => "DEFAULT" });
989 is($illrq_obj->getPrefix({ brw_cat => "UNKNOWN", branch => "HDE" }), "TEST",
990 "getPrefix: branch");
991 $config->set_series('getPrefixes',
992 { HDE => "TEST", TSL => "BAR", default => "DEFAULT" },
993 { A => "ATEST", C => "CBAR", default => "DEFAULT" });
994 is($illrq_obj->getPrefix({ branch => "UNKNOWN" }), "",
995 "getPrefix: default");
996 $config->set_always('getPrefixes', {});
997 is($illrq_obj->getPrefix({ branch => "UNKNOWN" }), "",
998 "getPrefix: the empty prefix");
1001 $config->set_series('getPrefixes',
1002 { HDE => "TEST", TSL => "BAR", default => "DEFAULT" },
1003 { AB => "ATEST", CD => "CBAR", default => "DEFAULT" });
1004 is($illrq_obj->id_prefix, "TEST-", "id_prefix: branch");
1005 $config->set_series('getPrefixes',
1006 { HDET => "TEST", TSLT => "BAR", default => "DEFAULT" },
1007 { AB => "ATEST", CD => "CBAR", default => "DEFAULT" });
1008 is($illrq_obj->id_prefix, "", "id_prefix: default");
1010 # requires_moderation
1011 $illrq_obj->status('NEW')->store;
1012 is($illrq_obj->requires_moderation, undef, "requires_moderation: No.");
1013 $illrq_obj->status('CANCREQ')->store;
1014 is($illrq_obj->requires_moderation, 'CANCREQ', "requires_moderation: Yes.");
1017 my $attr = Koha::MessageAttributes->find({ message_name => 'Ill_ready' });
1018 C4::Members::Messaging::SetMessagingPreference({
1019 borrowernumber => $patron->{borrowernumber},
1020 message_attribute_id => $attr->message_attribute_id,
1021 message_transport_types => ['email']
1023 my $return_patron = $illrq_obj->send_patron_notice('ILL_PICKUP_READY');
1024 my $notice = $schema->resultset('MessageQueue')->search({
1025 letter_code => 'ILL_PICKUP_READY',
1026 message_transport_type => 'email',
1027 borrowernumber => $illrq_obj->borrowernumber
1028 })->next()->letter_code;
1031 { result => { success => ['email'], fail => [] } },
1032 "Correct return when notice created"
1034 is($notice, 'ILL_PICKUP_READY' ,"Notice is correctly created");
1036 # ill update notice, passes additional text parameter
1037 my $attr_update = Koha::MessageAttributes->find({ message_name => 'Ill_update' });
1038 C4::Members::Messaging::SetMessagingPreference({
1039 borrowernumber => $patron->{borrowernumber},
1040 message_attribute_id => $attr_update->message_attribute_id,
1041 message_transport_types => ['email']
1043 my $return_patron_update = $illrq_obj->send_patron_notice('ILL_REQUEST_UPDATE', 'Some additional text');
1044 my $notice_update = $schema->resultset('MessageQueue')->search({
1045 letter_code => 'ILL_REQUEST_UPDATE',
1046 message_transport_type => 'email',
1047 borrowernumber => $illrq_obj->borrowernumber
1048 })->next()->letter_code;
1050 $return_patron_update,
1051 { result => { success => ['email'], fail => [] } },
1052 "Correct return when notice created"
1054 is($notice_update, 'ILL_REQUEST_UPDATE' ,"Notice is correctly created");
1057 my $return_patron_fail = $illrq_obj->send_patron_notice();
1059 $return_patron_fail,
1060 { error => 'notice_no_type' },
1061 "Correct error when missing type"
1065 # Specify that no staff notices should be send
1066 t::lib::Mocks::mock_preference('ILLSendStaffNotices', '');
1067 my $return_staff_cancel_fail =
1068 $illrq_obj->send_staff_notice('ILL_REQUEST_CANCEL');
1070 $return_staff_cancel_fail,
1071 { error => 'notice_not_enabled' },
1072 "Does not send notices that are not enabled"
1074 my $queue = $schema->resultset('MessageQueue')->search({
1075 letter_code => 'ILL_REQUEST_CANCEL'
1077 is($queue->count, 0, "Notice is not queued");
1079 # Specify that the cancel notice can be sent
1080 t::lib::Mocks::mock_preference('ILLSendStaffNotices', 'ILL_REQUEST_CANCEL');
1081 my $return_staff_cancel = $illrq_obj->send_staff_notice(
1082 'ILL_REQUEST_CANCEL'
1085 $return_staff_cancel,
1086 { success => 'notice_queued' },
1087 "Correct return when staff notice created"
1089 $queue = $schema->resultset('MessageQueue')->search({
1090 letter_code => 'ILL_REQUEST_CANCEL'
1092 is($queue->count, 1, "Notice queued as expected");
1094 my $return_staff_fail = $illrq_obj->send_staff_notice();
1097 { error => 'notice_no_type' },
1098 "Correct error when missing type"
1100 $queue = $schema->resultset('MessageQueue')->search({
1101 letter_code => 'ILL_REQUEST_CANCEL'
1103 is($queue->count, 1, "Notice is not queued");
1106 my $not = $illrq_obj->get_notice({
1107 notice_code => 'ILL_REQUEST_CANCEL',
1108 transport => 'email'
1111 # We test the properties of the hashref separately because the random
1112 # hash ordering of the metadata means we can't test the entire thing
1115 $not->{module} eq 'ill',
1116 'Correct module return from get_notice'
1119 $not->{name} eq 'ILL request cancelled',
1120 'Correct name return from get_notice'
1123 $not->{message_transport_type} eq 'email',
1124 'Correct message_transport_type return from get_notice'
1127 $not->{title} eq 'Interlibrary loan request cancelled',
1128 'Correct title return from get_notice'
1130 $not->{content} =~ s/\s//g;
1133 $not->{content},"Thepatronforinterlibraryloansrequest" . $illrq_obj->id . ",withthefollowingdetails,hasrequestedcancellationofthisILLrequest:-author:myauthor-title:mytitle",
1134 'Correct content returned from get_notice with metadata correctly ordered'
1137 $illrq_obj->append_to_note('Some text');
1139 $illrq_obj->notesstaff,
1141 'appending to a note works'
1144 $schema->storage->txn_rollback;
1148 subtest 'Censorship' => sub {
1152 $schema->storage->txn_begin;
1154 # Build infrastructure
1155 my $backend = Test::MockObject->new;
1156 $backend->set_isa('Koha::Illbackends::Mock');
1157 $backend->set_always('name', 'Mock');
1159 my $config = Test::MockObject->new;
1160 $config->set_always('backend_dir', "/tmp");
1162 my $illrq = $builder->build({source => 'Illrequest'});
1163 my $illrq_obj = Koha::Illrequests->find($illrq->{illrequest_id});
1164 $illrq_obj->_config($config);
1165 $illrq_obj->_backend($backend);
1167 $config->set_always('censorship', { censor_notes_staff => 1, censor_reply_date => 0 });
1169 my $censor_out = $illrq_obj->_censor({ foo => 'bar', baz => 564 });
1170 is_deeply($censor_out, { foo => 'bar', baz => 564, display_reply_date => 1 },
1171 "_censor: not OPAC, reply_date = 1");
1173 $censor_out = $illrq_obj->_censor({ foo => 'bar', baz => 564, opac => 1 });
1174 is_deeply($censor_out, {
1175 foo => 'bar', baz => 564, censor_notes_staff => 1,
1176 display_reply_date => 1, opac => 1
1177 }, "_censor: notes_staff = 0, reply_date = 0");
1179 $schema->storage->txn_rollback;
1182 subtest 'Checking out' => sub {
1186 $schema->storage->txn_begin;
1188 my $itemtype = $builder->build_object({
1189 class => 'Koha::ItemTypes',
1194 my $library = $builder->build_object({ class => 'Koha::Libraries' });
1195 my $biblio = $builder->build_sample_biblio();
1196 my $patron = $builder->build_object({ class => 'Koha::Patrons' });
1197 my $request = $builder->build_object({
1198 class => 'Koha::Illrequests',
1200 borrowernumber => $patron->borrowernumber,
1201 biblio_id => $biblio->biblionumber
1205 # First test that calling check_out without a stage param returns
1206 # what's required to build the form
1207 my $no_stage = $request->check_out();
1208 is($no_stage->{method}, 'check_out');
1209 is($no_stage->{stage}, 'form');
1210 isa_ok($no_stage->{value}, 'HASH');
1211 isa_ok($no_stage->{value}->{itemtypes}, 'Koha::ItemTypes');
1212 isa_ok($no_stage->{value}->{libraries}, 'Koha::Libraries');
1213 isa_ok($no_stage->{value}->{statistical}, 'Koha::Patrons');
1214 isa_ok($no_stage->{value}->{biblio}, 'Koha::Biblio');
1216 # Now test that form validation works when we supply a 'form' stage
1219 my $form_stage_missing_params = $request->check_out({
1222 is_deeply($form_stage_missing_params->{value}->{errors}, {
1225 # inhouse passed but not a valid patron
1226 my $form_stage_bad_patron = $request->check_out({
1228 item_type => $itemtype->itemtype,
1229 inhouse => 'I_DONT_EXIST'
1231 is_deeply($form_stage_bad_patron->{value}->{errors}, {
1234 # Too many items attached to biblio
1235 my $item1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
1236 my $item2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
1237 my $form_stage_two_items = $request->check_out({
1239 item_type => $itemtype->itemtype,
1241 is_deeply($form_stage_two_items->{value}->{errors}, {
1245 # Delete the items we created, so we can test that we can create one
1249 # We need to mock the user environment for AddIssue
1250 t::lib::Mocks::mock_userenv({ branchcode => $library->branchcode });
1253 # First we pass bad parameters to the item creation to test we're
1254 # catching the failure of item creation
1255 my $form_stage_bad_branchcode;
1257 $form_stage_bad_branchcode = $request->check_out({
1259 item_type => $itemtype->itemtype,
1262 } qr/DBD::mysql::st execute failed: Cannot add or update a child row: a foreign key constraint fails/,
1263 "Item creation fails on bad parameters";
1265 is_deeply($form_stage_bad_branchcode->{value}->{errors}, {
1267 },"We get expected failure of item creation");
1269 # Now create a proper item
1270 my $form_stage_good_branchcode = $request->check_out({
1272 item_type => $itemtype->itemtype,
1273 branchcode => $library->branchcode
1275 # By default, this item should not be loanable, so check that we're
1276 # informed of that fact
1278 $form_stage_good_branchcode->{value}->{check_out_errors},
1282 itemtype_notforloan => $itemtype->itemtype
1285 "We get expected error on notforloan of item"
1287 # Delete the item that was created
1288 $biblio->items->delete;
1289 # Now create an itemtype that is loanable
1290 my $itemtype_loanable = $builder->build_object({
1291 class => 'Koha::ItemTypes',
1296 # We need to mock the user environment for AddIssue
1297 t::lib::Mocks::mock_userenv({ branchcode => $library->branchcode });
1298 my $form_stage_loanable = $request->check_out({
1300 item_type => $itemtype_loanable->itemtype,
1301 branchcode => $library->branchcode
1303 is($form_stage_loanable->{stage}, 'done_check_out');
1304 isa_ok($patron->checkouts, 'Koha::Checkouts');
1305 is($patron->checkouts->count, 1);
1306 is($request->status, 'CHK');
1308 $schema->storage->txn_rollback;
1311 subtest 'Checking out with custom due date' => sub {
1313 $schema->storage->txn_begin;
1315 my $library = $builder->build_object({ class => 'Koha::Libraries' });
1316 my $patron = $builder->build_object({ class => 'Koha::Patrons' });
1317 my $biblio = $builder->build_sample_biblio();
1318 my $itemtype_loanable = $builder->build_object({
1319 class => 'Koha::ItemTypes',
1324 my $request = $builder->build_object({
1325 class => 'Koha::Illrequests',
1327 borrowernumber => $patron->borrowernumber,
1328 biblio_id => $biblio->biblionumber
1332 t::lib::Mocks::mock_userenv({ branchcode => $library->branchcode });
1333 my $duedate = '2099-05-21 00:00:00';
1334 my $form_stage_loanable = $request->check_out({
1336 item_type => $itemtype_loanable->itemtype,
1337 branchcode => $library->branchcode,
1340 is($patron->checkouts->next->date_due, $duedate, "Custom due date was used");
1342 $schema->storage->txn_rollback;
1345 subtest 'Checking Limits' => sub {
1349 $schema->storage->txn_begin;
1351 # Build infrastructure
1352 my $backend = Test::MockObject->new;
1353 $backend->set_isa('Koha::Illbackends::Mock');
1354 $backend->set_always('name', 'Mock');
1356 my $config = Test::MockObject->new;
1357 $config->set_always('backend_dir', "/tmp");
1359 my $illrq = $builder->build({source => 'Illrequest'});
1360 my $illrq_obj = Koha::Illrequests->find($illrq->{illrequest_id});
1361 $illrq_obj->_config($config);
1362 $illrq_obj->_backend($backend);
1365 $config->set_series('getLimitRules',
1366 { CPL => { count => 1, method => 'test' } },
1367 { default => { count => 0, method => 'active' } });
1368 is_deeply($illrq_obj->getLimits({ type => 'branch', value => "CPL" }),
1369 { count => 1, method => 'test' },
1370 "getLimits: by value.");
1371 is_deeply($illrq_obj->getLimits({ type => 'branch' }),
1372 { count => 0, method => 'active' },
1373 "getLimits: by default.");
1374 is_deeply($illrq_obj->getLimits({ type => 'branch', value => "CPL" }),
1375 { count => -1, method => 'active' },
1376 "getLimits: by hard-coded.");
1379 is($illrq_obj->_limit_counter('annual', { branchcode => $illrq_obj->branchcode }),
1380 1, "_limit_counter: Initial branch annual count.");
1381 is($illrq_obj->_limit_counter('active', { branchcode => $illrq_obj->branchcode }),
1382 1, "_limit_counter: Initial branch active count.");
1383 is($illrq_obj->_limit_counter('annual', { borrowernumber => $illrq_obj->borrowernumber }),
1384 1, "_limit_counter: Initial patron annual count.");
1385 is($illrq_obj->_limit_counter('active', { borrowernumber => $illrq_obj->borrowernumber }),
1386 1, "_limit_counter: Initial patron active count.");
1388 source => 'Illrequest',
1390 branchcode => $illrq_obj->branchcode,
1391 borrowernumber => $illrq_obj->borrowernumber,
1394 is($illrq_obj->_limit_counter('annual', { branchcode => $illrq_obj->branchcode }),
1395 2, "_limit_counter: Add a qualifying request for branch annual count.");
1396 is($illrq_obj->_limit_counter('active', { branchcode => $illrq_obj->branchcode }),
1397 2, "_limit_counter: Add a qualifying request for branch active count.");
1398 is($illrq_obj->_limit_counter('annual', { borrowernumber => $illrq_obj->borrowernumber }),
1399 2, "_limit_counter: Add a qualifying request for patron annual count.");
1400 is($illrq_obj->_limit_counter('active', { borrowernumber => $illrq_obj->borrowernumber }),
1401 2, "_limit_counter: Add a qualifying request for patron active count.");
1403 source => 'Illrequest',
1405 branchcode => $illrq_obj->branchcode,
1406 borrowernumber => $illrq_obj->borrowernumber,
1407 placed => "2005-05-31",
1410 is($illrq_obj->_limit_counter('annual', { branchcode => $illrq_obj->branchcode }),
1411 2, "_limit_counter: Add an out-of-date branch request.");
1412 is($illrq_obj->_limit_counter('active', { branchcode => $illrq_obj->branchcode }),
1413 3, "_limit_counter: Add a qualifying request for branch active count.");
1414 is($illrq_obj->_limit_counter('annual', { borrowernumber => $illrq_obj->borrowernumber }),
1415 2, "_limit_counter: Add an out-of-date patron request.");
1416 is($illrq_obj->_limit_counter('active', { borrowernumber => $illrq_obj->borrowernumber }),
1417 3, "_limit_counter: Add a qualifying request for patron active count.");
1419 source => 'Illrequest',
1421 branchcode => $illrq_obj->branchcode,
1422 borrowernumber => $illrq_obj->borrowernumber,
1426 is($illrq_obj->_limit_counter('annual', { branchcode => $illrq_obj->branchcode }),
1427 3, "_limit_counter: Add a qualifying request for branch annual count.");
1428 is($illrq_obj->_limit_counter('active', { branchcode => $illrq_obj->branchcode }),
1429 3, "_limit_counter: Add a completed request for branch active count.");
1430 is($illrq_obj->_limit_counter('annual', { borrowernumber => $illrq_obj->borrowernumber }),
1431 3, "_limit_counter: Add a qualifying request for patron annual count.");
1432 is($illrq_obj->_limit_counter('active', { borrowernumber => $illrq_obj->borrowernumber }),
1433 3, "_limit_counter: Add a completed request for patron active count.");
1437 # We've tested _limit_counter, so all we need to test here is whether the
1438 # current counts of 3 for each work as they should against different
1439 # configuration declarations.
1442 $config->set_always('getLimitRules', undef);
1443 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1444 librarycode => $illrq_obj->branchcode}),
1445 1, "check_limits: no configuration => no limits.");
1448 $config->set_always('getLimitRules',
1449 { $illrq_obj->branchcode => { count => 1, method => 'active' } });
1450 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1451 librarycode => $illrq_obj->branchcode}),
1452 0, "check_limits: branch active limit exceeded.");
1453 $config->set_always('getLimitRules',
1454 { $illrq_obj->branchcode => { count => 1, method => 'annual' } });
1455 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1456 librarycode => $illrq_obj->branchcode}),
1457 0, "check_limits: branch annual limit exceeded.");
1458 $config->set_always('getLimitRules',
1459 { $illrq_obj->branchcode => { count => 4, method => 'active' } });
1460 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1461 librarycode => $illrq_obj->branchcode}),
1462 1, "check_limits: branch active limit OK.");
1463 $config->set_always('getLimitRules',
1464 { $illrq_obj->branchcode => { count => 4, method => 'annual' } });
1465 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1466 librarycode => $illrq_obj->branchcode}),
1467 1, "check_limits: branch annual limit OK.");
1470 $config->set_always('getLimitRules',
1471 { $illrq_obj->patron->categorycode => { count => 1, method => 'active' } });
1472 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1473 librarycode => $illrq_obj->branchcode}),
1474 0, "check_limits: patron category active limit exceeded.");
1475 $config->set_always('getLimitRules',
1476 { $illrq_obj->patron->categorycode => { count => 1, method => 'annual' } });
1477 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1478 librarycode => $illrq_obj->branchcode}),
1479 0, "check_limits: patron category annual limit exceeded.");
1480 $config->set_always('getLimitRules',
1481 { $illrq_obj->patron->categorycode => { count => 4, method => 'active' } });
1482 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1483 librarycode => $illrq_obj->branchcode}),
1484 1, "check_limits: patron category active limit OK.");
1485 $config->set_always('getLimitRules',
1486 { $illrq_obj->patron->categorycode => { count => 4, method => 'annual' } });
1487 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1488 librarycode => $illrq_obj->branchcode}),
1489 1, "check_limits: patron category annual limit OK.");
1491 # One rule cancels the other
1492 $config->set_series('getLimitRules',
1493 # Branch rules allow request
1494 { $illrq_obj->branchcode => { count => 4, method => 'active' } },
1495 # Patron rule forbids it
1496 { $illrq_obj->patron->categorycode => { count => 1, method => 'annual' } });
1497 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1498 librarycode => $illrq_obj->branchcode}),
1499 0, "check_limits: patron category veto overrides branch OK.");
1500 $config->set_series('getLimitRules',
1501 # Branch rules allow request
1502 { $illrq_obj->branchcode => { count => 1, method => 'active' } },
1503 # Patron rule forbids it
1504 { $illrq_obj->patron->categorycode => { count => 4, method => 'annual' } });
1505 is($illrq_obj->check_limits({patron => $illrq_obj->patron,
1506 librarycode => $illrq_obj->branchcode}),
1507 0, "check_limits: branch veto overrides patron category OK.");
1509 $schema->storage->txn_rollback;
1512 subtest 'Custom statuses' => sub {
1516 $schema->storage->txn_begin;
1518 my $cat = Koha::AuthorisedValueCategories->search(
1520 category_name => 'ILLSTATUS'
1524 if ($cat->count == 0) {
1525 $cat = $builder->build_object(
1527 class => 'Koha::AuthorisedValueCategory',
1529 category_name => 'ILLSTATUS'
1535 my $av = $builder->build_object(
1537 class => 'Koha::AuthorisedValues',
1539 category => 'ILLSTATUS'
1544 is($av->category, 'ILLSTATUS',
1545 "Successfully created authorised value for custom status");
1547 my $ill_req = $builder->build_object(
1549 class => 'Koha::Illrequests',
1551 status_alias => $av->authorised_value
1555 isa_ok($ill_req->statusalias, 'Koha::AuthorisedValue',
1556 "statusalias correctly returning Koha::AuthorisedValue object");
1558 $ill_req->status("COMP");
1559 is($ill_req->statusalias, undef,
1560 "Koha::Illrequest->status overloading resetting status_alias");
1562 $schema->storage->txn_rollback;
1565 subtest 'Checking in hook' => sub {
1569 $schema->storage->txn_begin;
1571 # Build infrastructure
1572 my $backend = Test::MockObject->new;
1573 $backend->set_isa('Koha::Illbackends::Mock');
1574 $backend->set_always('name', 'Mock');
1576 my $config = Test::MockObject->new;
1577 $config->set_always('backend_dir', "/tmp");
1579 my $item = $builder->build_sample_item();
1580 my $patron = $builder->build_object({ class => 'Koha::Patrons' });
1582 t::lib::Mocks::mock_userenv(
1585 branchcode => $patron->branchcode
1589 my $illrq = $builder->build_object(
1591 class => 'Koha::Illrequests',
1593 biblio_id => $item->biblio->biblionumber,
1599 $illrq->_config($config);
1600 $illrq->_backend($backend);
1602 t::lib::Mocks::mock_preference('CirculateILL', 1);
1605 AddIssue( $patron->unblessed, $item->barcode );
1606 # Make the item withdrawn so checking-in is rejected
1607 t::lib::Mocks::mock_preference('BlockReturnOfWithdrawnItems', 1);
1608 $item->set({ withdrawn => 1 })->store;
1609 AddReturn( $item->barcode, $patron->branchcode );
1611 $illrq->discard_changes;
1612 isnt( $illrq->status, 'RET' );
1614 # allow the check-in
1615 $item->set({ withdrawn => 0 })->store;
1616 AddReturn( $item->barcode, $patron->branchcode );
1618 $illrq->discard_changes;
1619 is( $illrq->status, 'RET' );
1621 $schema->storage->txn_rollback;