Bug 18936: Convert issuingrules fields to circulation_rules
[koha.git] / t / db_dependent / Koha / IssuingRules.t
blob6c6d4ad4a647804f35ac856edace84503d52b605
1 #!/usr/bin/perl
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>.
20 use Modern::Perl;
22 use Test::More tests => 4;
24 use Benchmark;
26 use Koha::CirculationRules;
28 use t::lib::TestBuilder;
29 use t::lib::Mocks;
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 {
37 plan tests => 3;
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 {
47 plan tests => 4;
49 my $rule;
50 Koha::CirculationRules->delete;
52 is(Koha::CirculationRules->search->count, 0, 'There are no issuing rules.');
53 $rule = Koha::CirculationRules->get_effective_rule({
54 branchcode => undef,
55 categorycode => undef,
56 itemtype => undef,
57 rule_name => 'fine',
58 });
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({
62 branchcode => '*',
63 categorycode => '*',
64 itemtype => '*',
65 rule_name => 'fine',
66 })->store, 'Given I added an issuing rule branchcode => *,'
67 .' categorycode => *, itemtype => *,');
68 $rule = Koha::CirculationRules->get_effective_rule({
69 branchcode => '*',
70 categorycode => '*',
71 itemtype => '*',
72 rule_name => 'fine',
73 });
74 ok(_row_match($rule, '*', '*', '*'), 'When I attempt to get effective'
75 .' issuing rule by providing undefined values, then the above one is'
76 .' returned.');
79 subtest 'Get effective issuing rule in correct order' => sub {
80 plan tests => 18;
82 my $rule;
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,
89 rule_name => 'fine',
90 });
91 is($rule, undef, 'When I attempt to get effective issuing rule, then undef'
92 .' is returned.');
94 ok(Koha::CirculationRule->new({
95 branchcode => '*',
96 categorycode => '*',
97 itemtype => '*',
98 rule_name => 'fine',
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,
104 rule_name => 'fine',
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({
110 branchcode => '*',
111 categorycode => '*',
112 itemtype => $itemtype,
113 rule_name => 'fine',
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,
119 rule_name => 'fine',
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({
125 branchcode => '*',
126 categorycode => $categorycode,
127 itemtype => '*',
128 rule_name => 'fine',
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,
134 rule_name => 'fine',
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({
140 branchcode => '*',
141 categorycode => $categorycode,
142 itemtype => $itemtype,
143 rule_name => 'fine',
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,
149 rule_name => 'fine',
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,
156 categorycode => '*',
157 itemtype => '*',
158 rule_name => 'fine',
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,
164 rule_name => 'fine',
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,
171 categorycode => '*',
172 itemtype => $itemtype,
173 rule_name => 'fine',
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,
179 rule_name => 'fine',
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,
187 itemtype => '*',
188 rule_name => 'fine',
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,
194 rule_name => 'fine',
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,
203 rule_name => 'fine',
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,
209 rule_name => 'fine',
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 {
216 plan tests => 4;
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 {
270 plan tests => 4;
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',
279 value => {
280 homebranch => $library->branchcode,
281 holdingbranch => $library->branchcode,
282 notforloan => 0,
283 itemlost => 0,
284 withdrawn => 0,
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');
314 $patron->delete;
317 subtest 'get_onshelfholds_policy' => sub {
318 plan tests => 3;
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 {
334 plan tests => 1;
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
375 $issue_rule->delete;
376 is( Koha::CirculationRules->search()->count ,$count + 1, "We remove related circ rules maxissueqty and maxonsiteissueqty with our issuing rule");
380 sub _row_match {
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;