Line 0
Link Here
|
0 |
- |
1 |
#!/usr/bin/perl |
|
|
2 |
|
3 |
# Copyright 2016 Koha-Suomi Oy |
4 |
# |
5 |
# This file is part of Koha |
6 |
# |
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. |
11 |
# |
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. |
16 |
# |
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>. |
19 |
|
20 |
use Modern::Perl; |
21 |
|
22 |
use Test::More tests => 3; |
23 |
use Test::Deep qw( cmp_methods ); |
24 |
use Test::Exception; |
25 |
|
26 |
use Benchmark; |
27 |
|
28 |
use Koha::CirculationRules; |
29 |
|
30 |
use t::lib::TestBuilder; |
31 |
use t::lib::Mocks; |
32 |
|
33 |
my $schema = Koha::Database->new->schema; |
34 |
$schema->storage->txn_begin; |
35 |
|
36 |
my $builder = t::lib::TestBuilder->new; |
37 |
|
38 |
subtest 'get_effective_issuing_rule' => sub { |
39 |
plan tests => 3; |
40 |
|
41 |
my $categorycode = $builder->build({ source => 'Category' })->{'categorycode'}; |
42 |
my $itemtype = $builder->build({ source => 'Itemtype' })->{'itemtype'}; |
43 |
my $branchcode = $builder->build({ source => 'Branch' })->{'branchcode'}; |
44 |
|
45 |
subtest 'Priority rule' => sub { |
46 |
plan tests => 3; |
47 |
|
48 |
Koha::IssuingRules->delete; |
49 |
|
50 |
ok(Koha::IssuingRule->new({ |
51 |
branchcode => $branchcode, |
52 |
categorycode => $categorycode, |
53 |
itemtype => $itemtype, |
54 |
})->store, "Given I added an issuing rule branchcode => $branchcode,' |
55 |
.' categorycode => $categorycode, itemtype => $itemtype,"); |
56 |
|
57 |
ok(Koha::IssuingRule->new({ |
58 |
branchcode => '*', |
59 |
categorycode => $categorycode, |
60 |
itemtype => $itemtype, |
61 |
has_priority => 1, |
62 |
})->store, "Add a priority rule."); |
63 |
|
64 |
my $rule = Koha::IssuingRules->get_effective_issuing_rule({ |
65 |
branchcode => $branchcode, |
66 |
categorycode => $categorycode, |
67 |
itemtype => $itemtype, |
68 |
}); |
69 |
is($rule->has_priority, 1, 'Priority rule should be returned'); |
70 |
}; |
71 |
|
72 |
subtest 'Call with undefined values' => sub { |
73 |
plan tests => 5; |
74 |
|
75 |
my $rule; |
76 |
Koha::CirculationRules->delete; |
77 |
|
78 |
is(Koha::CirculationRules->search->count, 0, 'There are no issuing rules.'); |
79 |
# undef, undef, undef => 1 |
80 |
$rule = Koha::CirculationRules->get_effective_rule({ |
81 |
branchcode => undef, |
82 |
categorycode => undef, |
83 |
itemtype => undef, |
84 |
rule_name => 'fine', |
85 |
rule_value => 1, |
86 |
}); |
87 |
is($rule, undef, 'When I attempt to get effective issuing rule by' |
88 |
.' providing undefined values, then undef is returned.'); |
89 |
|
90 |
# undef, undef, undef => 2 |
91 |
ok( |
92 |
Koha::CirculationRule->new( |
93 |
{ |
94 |
branchcode => undef, |
95 |
categorycode => undef, |
96 |
itemtype => undef, |
97 |
rule_name => 'fine', |
98 |
rule_value => 2, |
99 |
} |
100 |
)->store, |
101 |
'Given I added an issuing rule branchcode => undef,' |
102 |
.' categorycode => undef, itemtype => undef,'); |
103 |
$rule = Koha::CirculationRules->get_effective_rule({ |
104 |
branchcode => undef, |
105 |
categorycode => undef, |
106 |
itemtype => undef, |
107 |
rule_name => 'fine', |
108 |
}); |
109 |
_is_row_match( |
110 |
$rule, |
111 |
{ |
112 |
branchcode => undef, |
113 |
categorycode => undef, |
114 |
itemtype => undef, |
115 |
rule_name => 'fine', |
116 |
rule_value => 2, |
117 |
}, |
118 |
'When I attempt to get effective' |
119 |
.' issuing rule by providing undefined values, then the above one is' |
120 |
.' returned.' |
121 |
); |
122 |
}; |
123 |
|
124 |
subtest 'Performance' => sub { |
125 |
plan tests => 4; |
126 |
|
127 |
my $worst_case = timethis(500, |
128 |
sub { Koha::CirculationRules->get_effective_rule({ |
129 |
branchcode => 'nonexistent', |
130 |
categorycode => 'nonexistent', |
131 |
itemtype => 'nonexistent', |
132 |
rule_name => 'nonexistent', |
133 |
}); |
134 |
} |
135 |
); |
136 |
my $mid_case = timethis(500, |
137 |
sub { Koha::CirculationRules->get_effective_rule({ |
138 |
branchcode => $branchcode, |
139 |
categorycode => 'nonexistent', |
140 |
itemtype => 'nonexistent', |
141 |
rule_name => 'nonexistent', |
142 |
}); |
143 |
} |
144 |
); |
145 |
my $sec_best_case = timethis(500, |
146 |
sub { Koha::CirculationRules->get_effective_rule({ |
147 |
branchcode => $branchcode, |
148 |
categorycode => $categorycode, |
149 |
itemtype => 'nonexistent', |
150 |
rule_name => 'nonexistent', |
151 |
}); |
152 |
} |
153 |
); |
154 |
my $best_case = timethis(500, |
155 |
sub { Koha::CirculationRules->get_effective_rule({ |
156 |
branchcode => $branchcode, |
157 |
categorycode => $categorycode, |
158 |
itemtype => $itemtype, |
159 |
rule_name => 'nonexistent', |
160 |
}); |
161 |
} |
162 |
); |
163 |
ok($worst_case, 'In worst case, get_effective_issuing_rule finds matching' |
164 |
.' rule '.sprintf('%.2f', $worst_case->iters/$worst_case->cpu_a) |
165 |
.' times per second.'); |
166 |
ok($mid_case, 'In mid case, get_effective_issuing_rule finds matching' |
167 |
.' rule '.sprintf('%.2f', $mid_case->iters/$mid_case->cpu_a) |
168 |
.' times per second.'); |
169 |
ok($sec_best_case, 'In second best case, get_effective_issuing_rule finds matching' |
170 |
.' rule '.sprintf('%.2f', $sec_best_case->iters/$sec_best_case->cpu_a) |
171 |
.' times per second.'); |
172 |
ok($best_case, 'In best case, get_effective_issuing_rule finds matching' |
173 |
.' rule '.sprintf('%.2f', $best_case->iters/$best_case->cpu_a) |
174 |
.' times per second.'); |
175 |
}; |
176 |
}; |
177 |
|
178 |
subtest 'set_rule' => sub { |
179 |
plan tests => 3; |
180 |
|
181 |
my $branchcode = $builder->build({ source => 'Branch' })->{'branchcode'}; |
182 |
my $categorycode = $builder->build({ source => 'Category' })->{'categorycode'}; |
183 |
my $itemtype = $builder->build({ source => 'Itemtype' })->{'itemtype'}; |
184 |
|
185 |
subtest 'Correct call' => sub { |
186 |
plan tests => 4; |
187 |
|
188 |
Koha::CirculationRules->delete; |
189 |
|
190 |
lives_ok( sub { |
191 |
Koha::CirculationRules->set_rule( { |
192 |
branchcode => $branchcode, |
193 |
rule_name => 'lostreturn', |
194 |
rule_value => '', |
195 |
} ); |
196 |
}, 'setting lostreturn with branch' ); |
197 |
|
198 |
lives_ok( sub { |
199 |
Koha::CirculationRules->set_rule( { |
200 |
branchcode => $branchcode, |
201 |
categorycode => $categorycode, |
202 |
rule_name => 'patron_maxissueqty', |
203 |
rule_value => '', |
204 |
} ); |
205 |
}, 'setting patron_maxissueqty with branch/category succeeds' ); |
206 |
|
207 |
lives_ok( sub { |
208 |
Koha::CirculationRules->set_rule( { |
209 |
branchcode => $branchcode, |
210 |
itemtype => $itemtype, |
211 |
rule_name => 'holdallowed', |
212 |
rule_value => '', |
213 |
} ); |
214 |
}, 'setting holdallowed with branch/itemtype succeeds' ); |
215 |
|
216 |
lives_ok( sub { |
217 |
Koha::CirculationRules->set_rule( { |
218 |
branchcode => $branchcode, |
219 |
categorycode => $categorycode, |
220 |
itemtype => $itemtype, |
221 |
rule_name => 'fine', |
222 |
rule_value => '', |
223 |
} ); |
224 |
}, 'setting fine with branch/category/itemtype succeeds' ); |
225 |
}; |
226 |
|
227 |
subtest 'Call with missing params' => sub { |
228 |
plan tests => 4; |
229 |
|
230 |
Koha::CirculationRules->delete; |
231 |
|
232 |
throws_ok( sub { |
233 |
Koha::CirculationRules->set_rule( { |
234 |
rule_name => 'lostreturn', |
235 |
rule_value => '', |
236 |
} ); |
237 |
}, qr/branchcode/, 'setting lostreturn without branch fails' ); |
238 |
|
239 |
throws_ok( sub { |
240 |
Koha::CirculationRules->set_rule( { |
241 |
branchcode => $branchcode, |
242 |
rule_name => 'patron_maxissueqty', |
243 |
rule_value => '', |
244 |
} ); |
245 |
}, qr/categorycode/, 'setting patron_maxissueqty without categorycode fails' ); |
246 |
|
247 |
throws_ok( sub { |
248 |
Koha::CirculationRules->set_rule( { |
249 |
branchcode => $branchcode, |
250 |
rule_name => 'holdallowed', |
251 |
rule_value => '', |
252 |
} ); |
253 |
}, qr/itemtype/, 'setting holdallowed without itemtype fails' ); |
254 |
|
255 |
throws_ok( sub { |
256 |
Koha::CirculationRules->set_rule( { |
257 |
branchcode => $branchcode, |
258 |
categorycode => $categorycode, |
259 |
rule_name => 'fine', |
260 |
rule_value => '', |
261 |
} ); |
262 |
}, qr/itemtype/, 'setting fine without itemtype fails' ); |
263 |
}; |
264 |
|
265 |
subtest 'Call with extra params' => sub { |
266 |
plan tests => 3; |
267 |
|
268 |
Koha::CirculationRules->delete; |
269 |
|
270 |
throws_ok( sub { |
271 |
Koha::CirculationRules->set_rule( { |
272 |
branchcode => $branchcode, |
273 |
categorycode => $categorycode, |
274 |
rule_name => 'lostreturn', |
275 |
rule_value => '', |
276 |
} ); |
277 |
}, qr/categorycode/, 'setting lostreturn with categorycode fails' ); |
278 |
|
279 |
throws_ok( sub { |
280 |
Koha::CirculationRules->set_rule( { |
281 |
branchcode => $branchcode, |
282 |
categorycode => $categorycode, |
283 |
itemtype => $itemtype, |
284 |
rule_name => 'patron_maxissueqty', |
285 |
rule_value => '', |
286 |
} ); |
287 |
}, qr/itemtype/, 'setting patron_maxissueqty with itemtype fails' ); |
288 |
|
289 |
throws_ok( sub { |
290 |
Koha::CirculationRules->set_rule( { |
291 |
branchcode => $branchcode, |
292 |
rule_name => 'holdallowed', |
293 |
categorycode => $categorycode, |
294 |
itemtype => $itemtype, |
295 |
rule_value => '', |
296 |
} ); |
297 |
}, qr/categorycode/, 'setting holdallowed with categorycode fails' ); |
298 |
}; |
299 |
}; |
300 |
|
301 |
subtest 'clone' => sub { |
302 |
plan tests => 2; |
303 |
|
304 |
my $branchcode = $builder->build({ source => 'Branch' })->{'branchcode'}; |
305 |
my $categorycode = $builder->build({ source => 'Category' })->{'categorycode'}; |
306 |
my $itemtype = $builder->build({ source => 'Itemtype' })->{'itemtype'}; |
307 |
|
308 |
subtest 'Clone multiple rules' => sub { |
309 |
plan tests => 4; |
310 |
|
311 |
Koha::CirculationRules->delete; |
312 |
|
313 |
Koha::CirculationRule->new({ |
314 |
branchcode => undef, |
315 |
categorycode => $categorycode, |
316 |
itemtype => $itemtype, |
317 |
rule_name => 'fine', |
318 |
rule_value => 5, |
319 |
})->store; |
320 |
|
321 |
Koha::CirculationRule->new({ |
322 |
branchcode => undef, |
323 |
categorycode => $categorycode, |
324 |
itemtype => $itemtype, |
325 |
rule_name => 'lengthunit', |
326 |
rule_value => 'days', |
327 |
})->store; |
328 |
|
329 |
Koha::CirculationRules->search({ branchcode => undef })->clone($branchcode); |
330 |
|
331 |
my $rule_fine = Koha::CirculationRules->get_effective_rule({ |
332 |
branchcode => $branchcode, |
333 |
categorycode => $categorycode, |
334 |
itemtype => $itemtype, |
335 |
rule_name => 'fine', |
336 |
}); |
337 |
my $rule_lengthunit = Koha::CirculationRules->get_effective_rule({ |
338 |
branchcode => $branchcode, |
339 |
categorycode => $categorycode, |
340 |
itemtype => $itemtype, |
341 |
rule_name => 'lengthunit', |
342 |
}); |
343 |
|
344 |
_is_row_match( |
345 |
$rule_fine, |
346 |
{ |
347 |
branchcode => $branchcode, |
348 |
categorycode => $categorycode, |
349 |
itemtype => $itemtype, |
350 |
rule_name => 'fine', |
351 |
rule_value => 5, |
352 |
}, |
353 |
'When I attempt to get cloned fine rule,' |
354 |
.' then the above one is returned.' |
355 |
); |
356 |
_is_row_match( |
357 |
$rule_lengthunit, |
358 |
{ |
359 |
branchcode => $branchcode, |
360 |
categorycode => $categorycode, |
361 |
itemtype => $itemtype, |
362 |
rule_name => 'lengthunit', |
363 |
rule_value => 'days', |
364 |
}, |
365 |
'When I attempt to get cloned lengthunit rule,' |
366 |
.' then the above one is returned.' |
367 |
); |
368 |
|
369 |
}; |
370 |
|
371 |
subtest 'Clone one rule' => sub { |
372 |
plan tests => 2; |
373 |
|
374 |
Koha::CirculationRules->delete; |
375 |
|
376 |
Koha::CirculationRule->new({ |
377 |
branchcode => undef, |
378 |
categorycode => $categorycode, |
379 |
itemtype => $itemtype, |
380 |
rule_name => 'fine', |
381 |
rule_value => 5, |
382 |
})->store; |
383 |
|
384 |
my $rule = Koha::CirculationRules->search({ branchcode => undef })->next; |
385 |
$rule->clone($branchcode); |
386 |
|
387 |
my $cloned_rule = Koha::CirculationRules->get_effective_rule({ |
388 |
branchcode => $branchcode, |
389 |
categorycode => $categorycode, |
390 |
itemtype => $itemtype, |
391 |
rule_name => 'fine', |
392 |
}); |
393 |
|
394 |
_is_row_match( |
395 |
$cloned_rule, |
396 |
{ |
397 |
branchcode => $branchcode, |
398 |
categorycode => $categorycode, |
399 |
itemtype => $itemtype, |
400 |
rule_name => 'fine', |
401 |
rule_value => '5', |
402 |
}, |
403 |
'When I attempt to get cloned fine rule,' |
404 |
.' then the above one is returned.' |
405 |
); |
406 |
|
407 |
}; |
408 |
}; |
409 |
|
410 |
sub _is_row_match { |
411 |
my ( $rule, $expected, $message ) = @_; |
412 |
|
413 |
ok( $rule, $message ) ? |
414 |
cmp_methods( $rule, [ %$expected ], $message ) : |
415 |
fail( $message ); |
416 |
} |
417 |
|
418 |
$schema->storage->txn_rollback; |