Line 0
Link Here
|
0 |
- |
1 |
#!/usr/bin/perl |
|
|
2 |
use Modern::Perl; |
3 |
|
4 |
use C4::Members; |
5 |
use C4::Circulation; |
6 |
use Koha::Database; |
7 |
use Koha::Patrons; |
8 |
use Koha::Patron; |
9 |
|
10 |
use Test::More tests => 62; |
11 |
|
12 |
use_ok('Koha::Patron'); |
13 |
|
14 |
use t::lib::TestBuilder; |
15 |
use t::lib::Mocks; |
16 |
|
17 |
my $schema = Koha::Database->new->schema; |
18 |
$schema->storage->txn_begin; |
19 |
|
20 |
my $builder = t::lib::TestBuilder->new; |
21 |
my $yesCatCode = $builder->build({ |
22 |
source => 'Category', |
23 |
value => { |
24 |
categorycode => 'yesCat', |
25 |
checkprevcheckout => 'yes', |
26 |
}, |
27 |
}); |
28 |
|
29 |
my $noCatCode = $builder->build({ |
30 |
source => 'Category', |
31 |
value => { |
32 |
categorycode => 'noCat', |
33 |
checkprevcheckout => 'no', |
34 |
}, |
35 |
}); |
36 |
|
37 |
my $inheritCatCode = $builder->build({ |
38 |
source => 'Category', |
39 |
value => { |
40 |
categorycode => 'inheritCat', |
41 |
checkprevcheckout => 'inherit', |
42 |
}, |
43 |
}); |
44 |
|
45 |
# Create context for some tests late on in the file. |
46 |
my $staff = $builder->build({source => 'Borrower'}); |
47 |
my @USERENV = ( |
48 |
$staff->{borrowernumber}, 'test', 'MASTERTEST', 'firstname', 'CPL', |
49 |
'CPL', 'email@example.org' |
50 |
); |
51 |
C4::Context->_new_userenv('DUMMY_SESSION_ID'); |
52 |
C4::Context->set_userenv(@USERENV); |
53 |
BAIL_OUT("No userenv") unless C4::Context->userenv; |
54 |
|
55 |
|
56 |
# wantsCheckPrevCheckout |
57 |
|
58 |
# We expect the following result matrix: |
59 |
# |
60 |
# (1/0 indicates the return value of WantsCheckPrevCheckout; i.e. 1 says we |
61 |
# should check whether the item was previously issued) |
62 |
# |
63 |
# | System Preference | hardyes | softyes | softno | hardno | |
64 |
# |-------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------| |
65 |
# | Category Setting | yes | no | inherit | yes | no | inherit | yes | no | inherit | yes | no | inherit | |
66 |
# |-------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| |
67 |
# | Patron Setting | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | |
68 |
# |-------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |
69 |
# | Expected Result | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
70 |
|
71 |
my $mappings = [ |
72 |
{ |
73 |
syspref => 'hardyes', |
74 |
categories => [ |
75 |
{ |
76 |
setting => 'yes', |
77 |
patrons => [ |
78 |
{setting => 'yes', result => 1}, |
79 |
{setting => 'no', result => 1}, |
80 |
{setting => 'inherit', result => 1}, |
81 |
], |
82 |
}, |
83 |
{ |
84 |
setting => 'no', |
85 |
patrons => [ |
86 |
{setting => 'yes', result => 1}, |
87 |
{setting => 'no', result => 1}, |
88 |
{setting => 'inherit', result => 1}, |
89 |
], |
90 |
}, |
91 |
{ |
92 |
setting => 'inherit', |
93 |
patrons => [ |
94 |
{setting => 'yes', result => 1}, |
95 |
{setting => 'no', result => 1}, |
96 |
{setting => 'inherit', result => 1}, |
97 |
], |
98 |
}, |
99 |
], |
100 |
}, |
101 |
{ |
102 |
syspref => 'softyes', |
103 |
categories => [ |
104 |
{ |
105 |
setting => 'yes', |
106 |
patrons => [ |
107 |
{setting => 'yes', result => 1}, |
108 |
{setting => 'no', result => 0}, |
109 |
{setting => 'inherit', result => 1}, |
110 |
], |
111 |
}, |
112 |
{ |
113 |
setting => 'no', |
114 |
patrons => [ |
115 |
{setting => 'yes', result => 1}, |
116 |
{setting => 'no', result => 0}, |
117 |
{setting => 'inherit', result => 0}, |
118 |
], |
119 |
}, |
120 |
{ |
121 |
setting => 'inherit', |
122 |
patrons => [ |
123 |
{setting => 'yes', result => 1}, |
124 |
{setting => 'no', result => 0}, |
125 |
{setting => 'inherit', result => 1}, |
126 |
], |
127 |
}, |
128 |
], |
129 |
}, |
130 |
{ |
131 |
syspref => 'softno', |
132 |
categories => [ |
133 |
{ |
134 |
setting => 'yes', |
135 |
patrons => [ |
136 |
{setting => 'yes', result => 1}, |
137 |
{setting => 'no', result => 0}, |
138 |
{setting => 'inherit', result => 1}, |
139 |
], |
140 |
}, |
141 |
{ |
142 |
setting => 'no', |
143 |
patrons => [ |
144 |
{setting => 'yes', result => 1}, |
145 |
{setting => 'no', result => 0}, |
146 |
{setting => 'inherit', result => 0}, |
147 |
], |
148 |
}, |
149 |
{ |
150 |
setting => 'inherit', |
151 |
patrons => [ |
152 |
{setting => 'yes', result => 1}, |
153 |
{setting => 'no', result => 0}, |
154 |
{setting => 'inherit', result => 0}, |
155 |
], |
156 |
}, |
157 |
], |
158 |
}, |
159 |
{ |
160 |
syspref => 'hardno', |
161 |
categories => [ |
162 |
{ |
163 |
setting => 'yes', |
164 |
patrons => [ |
165 |
{setting => 'yes', result => 0}, |
166 |
{setting => 'no', result => 0}, |
167 |
{setting => 'inherit', result => 0}, |
168 |
], |
169 |
}, |
170 |
{ |
171 |
setting => 'no', |
172 |
patrons => [ |
173 |
{setting => 'yes', result => 0}, |
174 |
{setting => 'no', result => 0}, |
175 |
{setting => 'inherit', result => 0}, |
176 |
], |
177 |
}, |
178 |
{ |
179 |
setting => 'inherit', |
180 |
patrons => [ |
181 |
{setting => 'yes', result => 0}, |
182 |
{setting => 'no', result => 0}, |
183 |
{setting => 'inherit', result => 0}, |
184 |
], |
185 |
}, |
186 |
], |
187 |
}, |
188 |
]; |
189 |
|
190 |
map { |
191 |
my $syspref = $_->{syspref}; |
192 |
t::lib::Mocks::mock_preference('checkprevcheckout', $syspref); |
193 |
map { |
194 |
my $code = $_->{setting} . 'Cat'; |
195 |
map { |
196 |
my $kpatron = $builder->build({ |
197 |
source => 'Borrower', |
198 |
value => { |
199 |
checkprevcheckout => $_->{setting}, |
200 |
categorycode => $code, |
201 |
}, |
202 |
}); |
203 |
my $patron = Koha::Patrons->find($kpatron->{borrowernumber}); |
204 |
is( |
205 |
$patron->wantsCheckPrevCheckout, $_->{result}, |
206 |
"Predicate with syspref " . $syspref . ", cat " . $code |
207 |
. ", patron " . $_->{setting} |
208 |
); |
209 |
} @{$_->{patrons}}; |
210 |
} @{$_->{categories}}; |
211 |
} @{$mappings}; |
212 |
|
213 |
# doCheckPrevCheckout |
214 |
|
215 |
# We want to test: |
216 |
# - DESCRIPTION [RETURNVALUE (0/1)] |
217 |
## PreIssue (sanity checks) |
218 |
# - Item, patron [0] |
219 |
# - Diff item, same bib, same patron [0] |
220 |
# - Diff item, diff bib, same patron [0] |
221 |
# - Same item, diff patron [0] |
222 |
# - Diff item, same bib, diff patron [0] |
223 |
# - Diff item, diff bib, diff patron [0] |
224 |
# - Serial item, serial bib, same patron [0] |
225 |
## PostIssue |
226 |
# - Same item, same patron [1] |
227 |
# - Diff item, same bib, same patron [1] |
228 |
# - Diff item, diff bib, same patron [0] |
229 |
# - Same item, diff patron [0] |
230 |
# - Diff item, same bib, diff patron [0] |
231 |
# - Diff item, diff bib, diff patron [0] |
232 |
# - Serial item, serial bib, same patron [0] |
233 |
## PostReturn |
234 |
# - Same item, same patron [1] |
235 |
# - Diff item, same bib, same patron [1] |
236 |
# - Diff item, diff bib, same patron [0] |
237 |
# - Same item, diff patron [0] |
238 |
# - Diff item, same bib, diff patron [0] |
239 |
# - Diff item, diff bib, diff patron [0] |
240 |
# - Serial item, serial bib, same patron [0] |
241 |
|
242 |
# Requirements: |
243 |
# $patron, $different_patron |
244 |
my $patron = $builder->build({ source => 'Borrower' }); |
245 |
my $patron_d = $builder->build({ source => 'Borrower' }); |
246 |
# $nonserialbibs $items (same bib number), $different_item (different bib) |
247 |
my $bib = $builder->build({ source => 'Biblio', value => { serial => 0 } }); |
248 |
my $item_1 = $builder->build({ |
249 |
source => 'Item', |
250 |
value => { biblionumber => $bib->{biblionumber} }, |
251 |
}); |
252 |
my $item_2 = $builder->build({ |
253 |
source => 'Item', |
254 |
value => { biblionumber => $item_1->{biblionumber} }, |
255 |
}); |
256 |
my $bib_d = $builder->build({ source => 'Biblio', value => { serial => 0 } }); |
257 |
my $item_d = $builder->build({ |
258 |
source => 'Item', |
259 |
value => { biblionumber => $bib_d->{biblionumber} }, |
260 |
}); |
261 |
# $serial bib, $serial item |
262 |
my $bib_s = $builder->build({ source => 'Biblio', value => { serial => 1 } }); |
263 |
my $item_s = $builder->build({ |
264 |
source => 'Item', |
265 |
value => { biblionumber => $bib_s->{biblionumber} }, |
266 |
}); |
267 |
|
268 |
## Testing Sub |
269 |
sub test_it { |
270 |
my ($mapping, $stage) = @_; |
271 |
map { |
272 |
my $patron = Koha::Patrons->find($_->{patron}->{borrowernumber}); |
273 |
is( |
274 |
$patron->doCheckPrevCheckout($_->{item}), |
275 |
$_->{result}, $stage . ": " . $_->{msg} |
276 |
); |
277 |
} @{$mapping}; |
278 |
}; |
279 |
|
280 |
## Initial Mappings |
281 |
my $cpvmappings = [ |
282 |
{ |
283 |
msg => "Item, patron [0]", |
284 |
item => $item_1, |
285 |
patron => $patron, |
286 |
result => 0, |
287 |
}, |
288 |
{ |
289 |
msg => "Diff item, same bib, same patron [0]", |
290 |
item => $item_2, |
291 |
patron => $patron, |
292 |
result => 0, |
293 |
}, |
294 |
{ |
295 |
msg => "Diff item, diff bib, same patron [0]", |
296 |
item => $item_d, |
297 |
patron => $patron, |
298 |
result => 0, |
299 |
}, |
300 |
{ |
301 |
msg => "Same item, diff patron [0]", |
302 |
item => $item_1, |
303 |
patron => $patron_d, |
304 |
result => 0, |
305 |
}, |
306 |
{ |
307 |
msg => "Diff item, same bib, diff patron [0]", |
308 |
item => $item_2, |
309 |
patron => $patron_d, |
310 |
result => 0, |
311 |
}, |
312 |
{ |
313 |
msg => "Diff item, diff bib, diff patron [0]", |
314 |
item => $item_d, |
315 |
patron => $patron_d, |
316 |
result => 0, |
317 |
}, |
318 |
{ |
319 |
msg => "Serial item, serial bib, same patron [0]", |
320 |
item => $item_s, |
321 |
patron => $patron, |
322 |
result => 0, |
323 |
}, |
324 |
]; |
325 |
|
326 |
test_it($cpvmappings, "PreIssue"); |
327 |
|
328 |
# Issue item_1, item_s to $patron: |
329 |
my $patron_get_mem = |
330 |
GetMember(%{{borrowernumber => $patron->{borrowernumber}}}); |
331 |
BAIL_OUT("Issue failed") |
332 |
unless AddIssue($patron_get_mem, $item_1->{barcode}); |
333 |
BAIL_OUT("Serial Issue failed") |
334 |
unless AddIssue($patron_get_mem, $item_s->{barcode}); |
335 |
|
336 |
# Then test: |
337 |
my $cpvPmappings = [ |
338 |
{ |
339 |
msg => "Same item, same patron [1]", |
340 |
item => $item_1, |
341 |
patron => $patron, |
342 |
result => 1, |
343 |
}, |
344 |
{ |
345 |
msg => "Diff item, same bib, same patron [1]", |
346 |
item => $item_2, |
347 |
patron => $patron, |
348 |
result => 1, |
349 |
}, |
350 |
{ |
351 |
msg => "Diff item, diff bib, same patron [0]", |
352 |
item => $item_d, |
353 |
patron => $patron, |
354 |
result => 0, |
355 |
}, |
356 |
{ |
357 |
msg => "Same item, diff patron [0]", |
358 |
item => $item_1, |
359 |
patron => $patron_d, |
360 |
result => 0, |
361 |
}, |
362 |
{ |
363 |
msg => "Diff item, same bib, diff patron [0]", |
364 |
item => $item_2, |
365 |
patron => $patron_d, |
366 |
result => 0, |
367 |
}, |
368 |
{ |
369 |
msg => "Diff item, diff bib, diff patron [0]", |
370 |
item => $item_d, |
371 |
patron => $patron_d, |
372 |
result => 0, |
373 |
}, |
374 |
{ |
375 |
msg => "Serial item, serial bib, same patron [0]", |
376 |
item => $item_s, |
377 |
patron => $patron, |
378 |
result => 0, |
379 |
}, |
380 |
]; |
381 |
|
382 |
test_it($cpvPmappings, "PostIssue"); |
383 |
|
384 |
# Return item_1, item_s from patron: |
385 |
BAIL_OUT("Return Failed") |
386 |
unless AddReturn($item_1->{barcode}, $patron->{branchcode}); |
387 |
BAIL_OUT("Serial Return Failed") |
388 |
unless AddReturn($item_s->{barcode}, $patron->{branchcode}); |
389 |
|
390 |
# Then: |
391 |
test_it($cpvPmappings, "PostReturn"); |
392 |
|
393 |
# Finally test C4::Circulation::CanBookBeIssued |
394 |
|
395 |
# We have already tested ->wantsCheckPrevCheckout and ->doCheckPrevCheckout, |
396 |
# so all that remains to be tested is whetherthe different combinational |
397 |
# outcomes of the above return values in CanBookBeIssued result in the |
398 |
# approriate $needsconfirmation. |
399 |
|
400 |
# We want to test: |
401 |
# - DESCRIPTION [RETURNVALUE (0/1)] |
402 |
# - patron, !wantsCheckPrevCheckout, !doCheckPrevCheckout |
403 |
# [!$issuingimpossible,!$needsconfirmation->{PREVISSUE}] |
404 |
# - patron, wantsCheckPrevCheckout, !doCheckPrevCheckout |
405 |
# [!$issuingimpossible,!$needsconfirmation->{PREVISSUE}] |
406 |
# - patron, !wantsCheckPrevCheckout, doCheckPrevCheckout |
407 |
# [!$issuingimpossible,!$needsconfirmation->{PREVISSUE}] |
408 |
# - patron, wantsCheckPrevCheckout, doCheckPrevCheckout |
409 |
# [!$issuingimpossible,$needsconfirmation->{PREVISSUE}] |
410 |
|
411 |
# Needs: |
412 |
# - $patron_from_GetMember |
413 |
# - $item objects (one not issued, another prevIssued) |
414 |
# - $checkprevcheckout pref (first hardno, then hardyes) |
415 |
|
416 |
# Our Patron |
417 |
my $CBBI_patron = $builder->build({source => 'Borrower'}); |
418 |
my $p_from_GetMember = |
419 |
GetMember(%{{borrowernumber => $CBBI_patron->{borrowernumber}}}); |
420 |
# Our Items |
421 |
my $new_bib = $builder->build({ |
422 |
source => 'Biblio', |
423 |
value => { serial => 0 } |
424 |
}); |
425 |
my $new_item = $builder->build({ |
426 |
source => 'Item', |
427 |
value => { |
428 |
notforloan => 0, |
429 |
withdrawn => 0, |
430 |
itemlost => 0, |
431 |
biblionumber => $new_bib->{biblionumber}, |
432 |
}, |
433 |
}); |
434 |
my $prev_bib = $builder->build({ |
435 |
source => 'Biblio', |
436 |
value => { serial => 0 } |
437 |
}); |
438 |
my $prev_item = $builder->build({ |
439 |
source => 'Item', |
440 |
value => { |
441 |
notforloan => 0, |
442 |
withdrawn => 0, |
443 |
itemlost => 0, |
444 |
biblionumber => $prev_bib->{biblionumber}, |
445 |
}, |
446 |
}); |
447 |
# Second is Checked Out |
448 |
BAIL_OUT("CanBookBeIssued Issue failed") |
449 |
unless AddIssue($p_from_GetMember, $prev_item->{barcode}); |
450 |
|
451 |
# Mappings |
452 |
my $CBBI_mappings = [ |
453 |
{ |
454 |
syspref => 'hardno', |
455 |
item => $new_item, |
456 |
result => undef, |
457 |
msg => "patron, !wantsCheckPrevCheckout, !doCheckPrevCheckout" |
458 |
|
459 |
}, |
460 |
{ |
461 |
syspref => 'hardyes', |
462 |
item => $new_item, |
463 |
result => undef, |
464 |
msg => "patron, wantsCheckPrevCheckout, !doCheckPrevCheckout" |
465 |
}, |
466 |
{ |
467 |
syspref => 'hardno', |
468 |
item => $prev_item, |
469 |
result => undef, |
470 |
msg => "patron, !wantsCheckPrevCheckout, doCheckPrevCheckout" |
471 |
}, |
472 |
{ |
473 |
syspref => 'hardyes', |
474 |
item => $prev_item, |
475 |
result => 1, |
476 |
msg => "patron, wantsCheckPrevCheckout, doCheckPrevCheckout" |
477 |
}, |
478 |
]; |
479 |
|
480 |
# Tests |
481 |
map { |
482 |
t::lib::Mocks::mock_preference('checkprevcheckout', $_->{syspref}); |
483 |
my ( $issuingimpossible, $needsconfirmation ) = |
484 |
C4::Circulation::CanBookBeIssued( |
485 |
$p_from_GetMember, $_->{item}->{barcode} |
486 |
); |
487 |
is($needsconfirmation->{PREVISSUE}, $_->{result}, $_->{msg}); |
488 |
} @{$CBBI_mappings}; |
489 |
|
490 |
$schema->storage->txn_rollback; |
491 |
|
492 |
1; |