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