3 # Copyright 2016 Koha-Suomi Oy
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;
26 use Koha
::CirculationRules
;
28 use t
::lib
::TestBuilder
;
31 my $schema = Koha
::Database
->new->schema;
32 $schema->storage->txn_begin;
34 my $builder = t
::lib
::TestBuilder
->new;
36 subtest
'get_effective_issuing_rule' => sub {
39 my $patron = $builder->build({ source
=> 'Borrower' });
40 my $item = $builder->build({ source
=> 'Item' });
42 my $categorycode = $patron->{'categorycode'};
43 my $itemtype = $item->{'itype'};
44 my $branchcode = $item->{'homebranch'};
46 subtest
'Call with undefined values' => sub {
50 Koha
::CirculationRules
->delete;
52 is
(Koha
::CirculationRules
->search->count, 0, 'There are no issuing rules.');
53 $rule = Koha
::CirculationRules
->get_effective_rule({
55 categorycode
=> undef,
59 is
($rule, undef, 'When I attempt to get effective issuing rule by'
60 .' providing undefined values, then undef is returned.');
61 ok
(Koha
::CirculationRule
->new({
66 })->store, 'Given I added an issuing rule branchcode => *,'
67 .' categorycode => *, itemtype => *,');
68 $rule = Koha
::CirculationRules
->get_effective_rule({
74 ok
(_row_match
($rule, '*', '*', '*'), 'When I attempt to get effective'
75 .' issuing rule by providing undefined values, then the above one is'
79 subtest
'Get effective issuing rule in correct order' => sub {
83 Koha
::CirculationRules
->delete;
84 is
(Koha
::CirculationRules
->search->count, 0, 'There are no issuing rules.');
85 $rule = Koha
::CirculationRules
->get_effective_rule({
86 branchcode
=> $branchcode,
87 categorycode
=> $categorycode,
88 itemtype
=> $itemtype,
91 is
($rule, undef, 'When I attempt to get effective issuing rule, then undef'
94 ok
(Koha
::CirculationRule
->new({
99 })->store, 'Given I added an issuing rule branchcode => *, categorycode => *, itemtype => *,');
100 $rule = Koha
::CirculationRules
->get_effective_rule({
101 branchcode
=> $branchcode,
102 categorycode
=> $categorycode,
103 itemtype
=> $itemtype,
106 ok
(_row_match
($rule, '*', '*', '*'), 'When I attempt to get effective issuing rule,'
107 .' then the above one is returned.');
109 ok
(Koha
::CirculationRule
->new({
112 itemtype
=> $itemtype,
114 })->store, "Given I added an issuing rule branchcode => *, categorycode => *, itemtype => $itemtype,");
115 $rule = Koha
::CirculationRules
->get_effective_rule({
116 branchcode
=> $branchcode,
117 categorycode
=> $categorycode,
118 itemtype
=> $itemtype,
121 ok
(_row_match
($rule, '*', '*', $itemtype), 'When I attempt to get effective issuing rule,'
122 .' then the above one is returned.');
124 ok
(Koha
::CirculationRule
->new({
126 categorycode
=> $categorycode,
129 })->store, "Given I added an issuing rule branchcode => *, categorycode => $categorycode, itemtype => *,");
130 $rule = Koha
::CirculationRules
->get_effective_rule({
131 branchcode
=> $branchcode,
132 categorycode
=> $categorycode,
133 itemtype
=> $itemtype,
136 ok
(_row_match
($rule, '*', $categorycode, '*'), 'When I attempt to get effective issuing rule,'
137 .' then the above one is returned.');
139 ok
(Koha
::CirculationRule
->new({
141 categorycode
=> $categorycode,
142 itemtype
=> $itemtype,
144 })->store, "Given I added an issuing rule branchcode => *, categorycode => $categorycode, itemtype => $itemtype,");
145 $rule = Koha
::CirculationRules
->get_effective_rule({
146 branchcode
=> $branchcode,
147 categorycode
=> $categorycode,
148 itemtype
=> $itemtype,
151 ok
(_row_match
($rule, '*', $categorycode, $itemtype), 'When I attempt to get effective issuing rule,'
152 .' then the above one is returned.');
154 ok
(Koha
::CirculationRule
->new({
155 branchcode
=> $branchcode,
159 })->store, "Given I added an issuing rule branchcode => $branchcode, categorycode => '*', itemtype => '*',");
160 $rule = Koha
::CirculationRules
->get_effective_rule({
161 branchcode
=> $branchcode,
162 categorycode
=> $categorycode,
163 itemtype
=> $itemtype,
166 ok
(_row_match
($rule, $branchcode, '*', '*'), 'When I attempt to get effective issuing rule,'
167 .' then the above one is returned.');
169 ok
(Koha
::CirculationRule
->new({
170 branchcode
=> $branchcode,
172 itemtype
=> $itemtype,
174 })->store, "Given I added an issuing rule branchcode => $branchcode, categorycode => '*', itemtype => $itemtype,");
175 $rule = Koha
::CirculationRules
->get_effective_rule({
176 branchcode
=> $branchcode,
177 categorycode
=> $categorycode,
178 itemtype
=> $itemtype,
181 ok
(_row_match
($rule, $branchcode, '*', $itemtype), 'When I attempt to get effective issuing rule,'
182 .' then the above one is returned.');
184 ok
(Koha
::CirculationRule
->new({
185 branchcode
=> $branchcode,
186 categorycode
=> $categorycode,
189 })->store, "Given I added an issuing rule branchcode => $branchcode, categorycode => $categorycode, itemtype => '*',");
190 $rule = Koha
::CirculationRules
->get_effective_rule({
191 branchcode
=> $branchcode,
192 categorycode
=> $categorycode,
193 itemtype
=> $itemtype,
196 ok
(_row_match
($rule, $branchcode, $categorycode, '*'), 'When I attempt to get effective issuing rule,'
197 .' then the above one is returned.');
199 ok
(Koha
::CirculationRule
->new({
200 branchcode
=> $branchcode,
201 categorycode
=> $categorycode,
202 itemtype
=> $itemtype,
204 })->store, "Given I added an issuing rule branchcode => $branchcode, categorycode => $categorycode, itemtype => $itemtype,");
205 $rule = Koha
::CirculationRules
->get_effective_rule({
206 branchcode
=> $branchcode,
207 categorycode
=> $categorycode,
208 itemtype
=> $itemtype,
211 ok
(_row_match
($rule, $branchcode, $categorycode, $itemtype), 'When I attempt to get effective issuing rule,'
212 .' then the above one is returned.');
215 subtest
'Performance' => sub {
218 my $worst_case = timethis
(500,
219 sub { Koha
::CirculationRules
->get_effective_rule({
220 branchcode
=> 'nonexistent',
221 categorycode
=> 'nonexistent',
222 itemtype
=> 'nonexistent',
223 rule_name
=> 'nonexistent',
227 my $mid_case = timethis
(500,
228 sub { Koha
::CirculationRules
->get_effective_rule({
229 branchcode
=> $branchcode,
230 categorycode
=> 'nonexistent',
231 itemtype
=> 'nonexistent',
232 rule_name
=> 'nonexistent',
236 my $sec_best_case = timethis
(500,
237 sub { Koha
::CirculationRules
->get_effective_rule({
238 branchcode
=> $branchcode,
239 categorycode
=> $categorycode,
240 itemtype
=> 'nonexistent',
241 rule_name
=> 'nonexistent',
245 my $best_case = timethis
(500,
246 sub { Koha
::CirculationRules
->get_effective_rule({
247 branchcode
=> $branchcode,
248 categorycode
=> $categorycode,
249 itemtype
=> $itemtype,
250 rule_name
=> 'nonexistent',
254 ok
($worst_case, 'In worst case, get_effective_issuing_rule finds matching'
255 .' rule '.sprintf('%.2f', $worst_case->iters/$worst_case->cpu_a)
256 .' times per second.');
257 ok
($mid_case, 'In mid case, get_effective_issuing_rule finds matching'
258 .' rule '.sprintf('%.2f', $mid_case->iters/$mid_case->cpu_a)
259 .' times per second.');
260 ok
($sec_best_case, 'In second best case, get_effective_issuing_rule finds matching'
261 .' rule '.sprintf('%.2f', $sec_best_case->iters/$sec_best_case->cpu_a)
262 .' times per second.');
263 ok
($best_case, 'In best case, get_effective_issuing_rule finds matching'
264 .' rule '.sprintf('%.2f', $best_case->iters/$best_case->cpu_a)
265 .' times per second.');
269 subtest
'get_opacitemholds_policy' => sub {
271 my $itype = $builder->build_object({ class => 'Koha::ItemTypes' });
272 my $itemtype = $builder->build_object({ class => 'Koha::ItemTypes' });
273 my $library = $builder->build_object({ class => 'Koha::Libraries' });
274 my $patron = $builder->build_object({ class => 'Koha::Patrons' });
275 my $biblio = $builder->build_object({ class => 'Koha::Biblios' });
276 my $biblioitem = $builder->build_object( { class => 'Koha::Biblioitems', value
=> { itemtype
=> $itemtype->itemtype, biblionumber
=> $biblio->biblionumber } } );
277 my $item = $builder->build_object(
278 { class => 'Koha::Items',
280 homebranch
=> $library->branchcode,
281 holdingbranch
=> $library->branchcode,
285 biblionumber
=> $biblio->biblionumber,
286 biblioitemnumber
=> $biblioitem->biblioitemnumber,
287 itype
=> $itype->itemtype,
292 Koha
::IssuingRules
->delete;
293 Koha
::IssuingRule
->new({categorycode
=> '*', itemtype
=> '*', branchcode
=> '*', opacitemholds
=> "N"})->store;
294 Koha
::IssuingRule
->new({categorycode
=> '*', itemtype
=> $itype->itemtype, branchcode
=> '*', opacitemholds
=> "Y"})->store;
295 Koha
::IssuingRule
->new({categorycode
=> '*', itemtype
=> $itemtype->itemtype, branchcode
=> '*', opacitemholds
=> "N"})->store;
296 t
::lib
::Mocks
::mock_preference
('item-level_itypes', 1);
297 my $opacitemholds = Koha
::IssuingRules
->get_opacitemholds_policy( { item
=> $item, patron
=> $patron } );
298 is
( $opacitemholds, 'Y', 'Patrons can place a hold on this itype');
299 t
::lib
::Mocks
::mock_preference
('item-level_itypes', 0);
300 $opacitemholds = Koha
::IssuingRules
->get_opacitemholds_policy( { item
=> $item, patron
=> $patron } );
301 is
( $opacitemholds, 'N', 'Patrons cannot place a hold on this itemtype');
303 Koha
::IssuingRules
->delete;
304 Koha
::IssuingRule
->new({categorycode
=> '*', itemtype
=> '*', branchcode
=> '*', opacitemholds
=> "N"})->store;
305 Koha
::IssuingRule
->new({categorycode
=> '*', itemtype
=> $itype->itemtype, branchcode
=> '*', opacitemholds
=> "N"})->store;
306 Koha
::IssuingRule
->new({categorycode
=> '*', itemtype
=> $itemtype->itemtype, branchcode
=> '*', opacitemholds
=> "Y"})->store;
307 t
::lib
::Mocks
::mock_preference
('item-level_itypes', 1);
308 $opacitemholds = Koha
::IssuingRules
->get_opacitemholds_policy( { item
=> $item, patron
=> $patron } );
309 is
( $opacitemholds, 'N', 'Patrons cannot place a hold on this itype');
310 t
::lib
::Mocks
::mock_preference
('item-level_itypes', 0);
311 $opacitemholds = Koha
::IssuingRules
->get_opacitemholds_policy( { item
=> $item, patron
=> $patron } );
312 is
( $opacitemholds, 'Y', 'Patrons can place a hold on this itemtype');
317 subtest
'get_onshelfholds_policy' => sub {
320 t
::lib
::Mocks
::mock_preference
('item-level_itypes', 1);
321 Koha
::IssuingRules
->delete;
323 my $patron = $builder->build_object({ class => 'Koha::Patrons' });
324 my $item = $builder->build_object({ class => 'Koha::Items' });
326 is
( Koha
::IssuingRules
->get_onshelfholds_policy({ item
=> $item, patron
=> $patron }), undef, 'Should return undef when no rules can be found' );
327 Koha
::IssuingRule
->new({ categorycode
=> $patron->categorycode, itemtype
=> $item->itype, branchcode
=> '*', onshelfholds
=> "0" })->store;
328 is
( Koha
::IssuingRules
->get_onshelfholds_policy({ item
=> $item, patron
=> $patron }), 0, 'Should be zero' );
329 Koha
::IssuingRule
->new({ categorycode
=> $patron->categorycode, itemtype
=> $item->itype, branchcode
=> $item->holdingbranch, onshelfholds
=> "2" })->store;
330 is
( Koha
::IssuingRules
->get_onshelfholds_policy({ item
=> $item, patron
=> $patron }), 2, 'Should be two now' );
333 subtest
'delete' => sub {
336 my $itemtype = $builder->build_object({ class => 'Koha::ItemTypes' });
337 my $library = $builder->build_object({ class => 'Koha::Libraries' });
338 my $category = $builder->build_object({ class => 'Koha::Patron::Categories' });
340 # We make an issuing rule
341 my $issue_rule = $builder->build_object({ class => 'Koha::IssuingRules', value
=> {
342 categorycode
=> $category->categorycode,
343 itemtype
=> $itemtype->itemtype,
344 branchcode
=> $library->branchcode
348 my $count = Koha
::CirculationRules
->search()->count;
349 # Note how many circulation rules we start with
351 # We make some circulation rules for the same thing
352 $builder->build_object({ class => 'Koha::CirculationRules', value
=> {
353 categorycode
=> $category->categorycode,
354 itemtype
=> $itemtype->itemtype,
355 branchcode
=> $library->branchcode,
356 rule_name
=> 'maxissueqty',
359 $builder->build_object({ class => 'Koha::CirculationRules', value
=> {
360 categorycode
=> $category->categorycode,
361 itemtype
=> $itemtype->itemtype,
362 branchcode
=> $library->branchcode,
363 rule_name
=> 'maxonsiteissueqty',
366 $builder->build_object({ class => 'Koha::CirculationRules', value
=> {
367 categorycode
=> $category->categorycode,
368 itemtype
=> $itemtype->itemtype,
369 branchcode
=> $library->branchcode,
370 rule_name
=> 'another_rule', # That must not be deleted
374 # Now we delete the issuing rule
376 is
( Koha
::CirculationRules
->search()->count ,$count + 1, "We remove related circ rules maxissueqty and maxonsiteissueqty with our issuing rule");
381 my ($rule, $branchcode, $categorycode, $itemtype) = @_;
383 return $rule->branchcode eq $branchcode && $rule->categorycode eq $categorycode
384 && $rule->itemtype eq $itemtype;
387 $schema->storage->txn_rollback;