5e74c9cf37f2908de2fbbccea200298a1c288234
[Evergreen.git] / Open-ILS / src / perlmods / live_t / 25-lp1694058-multiple-hold-placement.t
1 #!perl
2 use strict; use warnings;
3 use Test::More tests => 30;
4 use OpenILS::Utils::TestUtils;
5 use OpenILS::Const qw(:const);
6
7 diag("Test LP 1694058 multiple hold placement.");
8
9 my $script = OpenILS::Utils::TestUtils->new();
10 my $U = 'OpenILS::Application::AppUtils';
11
12 use constant {
13     BR1_WORKSTATION => 'BR1-test-lp1694058-multiple-hold-placement.t',
14     BR1_ID => 4,
15     BR2_ID => 5,
16     PATRON1_BARCODE => '99999376864',
17     PATRON2_BARCODE => '99999342948',
18     RECORD_ID => 3,
19     METARECORD_ID => 13,
20     COPY_ID => 2503,
21 };
22
23 # Keep track of hold ids, so we can cancel them later.
24 my @holds = ();
25
26 # Login as admin at BR1.
27 my $authtoken = $script->authenticate({
28     username=>'admin',
29     password=>'demo123',
30     type=>'staff'
31 });
32 ok(
33     $script->authtoken,
34     'Have an authtoken'
35 );
36
37 # Register workstation.
38 my $ws = $script->find_or_register_workstation(BR1_WORKSTATION, BR1_ID);
39 ok(
40     ! ref $ws,
41     'Found or registered workstation'
42 );
43
44 # Logout.
45 $script->logout();
46 ok(
47     ! $script->authtoken,
48     'Successfully logged out'
49 );
50
51 # Login as admin at BR1 using the workstation.
52 $authtoken = $script->authenticate({
53     username=>'admin',
54     password=>'demo123',
55     type=>'staff',
56     workstation => BR1_WORKSTATION
57 });
58 ok(
59     $script->authtoken,
60     'Have an authtoken'
61 );
62
63 # Check that OILS_SETTING_MAX_DUPLICATE_HOLDS is not set at BR1 and ancestors.
64 my $setting_value = $U->ou_ancestor_setting_value(BR1_ID, OILS_SETTING_MAX_DUPLICATE_HOLDS);
65 ok(
66     ! $setting_value,
67     'circ.holds.max_duplicate_holds is not set for BR1'
68 );
69
70 # Check that OILS_SETTING_MAX_DUPLICATE_HOLDS is not set at BR2 and ancestors.
71 $setting_value = $U->ou_ancestor_setting_value(BR2_ID, OILS_SETTING_MAX_DUPLICATE_HOLDS);
72 ok(
73     ! $setting_value,
74     'circ.holds.max_duplicate_holds is not set for BR2'
75 );
76
77 # Set OILS_SETTING_MAX_DUPLICATE_HOLDS to 5 at BR1.
78 $setting_value = $U->simplereq(
79     'open-ils.actor',
80     'open-ils.actor.org_unit.settings.update',
81     $authtoken,
82     BR1_ID,
83     {OILS_SETTING_MAX_DUPLICATE_HOLDS, 5}
84 );
85 ok(
86     ! ref $setting_value,
87     'circ.holds.max_duplicate_holds set to 5 for BR1'
88 );
89
90 # Retrieve PATRON1.
91 my $patron1 = $U->simplereq(
92     'open-ils.actor',
93     'open-ils.actor.user.fleshed.retrieve_by_barcode',
94     $authtoken,
95     PATRON1_BARCODE
96 );
97 isa_ok(
98     ref $patron1,
99     'Fieldmapper::actor::user',
100     'Got patron 1'
101 ) or BAIL_OUT('Need Patron1');
102
103 # Create a circ session for holds placement.
104 my $circ_session = $script->session('open-ils.circ');
105
106 # Place 5 holds for RECORD_ID for PATRON1. Expect success.
107 my $request = $circ_session->request(
108     'open-ils.circ.holds.test_and_create.batch',
109     $authtoken,
110     {
111         hold_type => 'T',
112         patronid => $patron1->id(),
113         pickup_lib => $patron1->home_ou()
114     },
115     [RECORD_ID, RECORD_ID, RECORD_ID, RECORD_ID, RECORD_ID]
116 );
117 my $success = 0;
118 while (my $response = $request->recv()) {
119     my $result = $response->content();
120     if ($result->{result} && !ref $result->{result}) {
121         $success++;
122         push(@holds, $result->{result});
123     }
124 }
125 $request->finish();
126 is(
127     $success,
128     5,
129     'Placed 5 title holds for Patron 1'
130 );
131
132 # Place 1 hold for RECORD_ID for PATRON1. Expect HOLD_EXISTS.
133 $request = $circ_session->request(
134     'open-ils.circ.holds.test_and_create.batch',
135     $authtoken,
136     {
137         hold_type => 'T',
138         patronid => $patron1->id(),
139         pickup_lib => $patron1->home_ou()
140     },
141     [RECORD_ID]
142 );
143 my $textcode;
144 while (my $response = $request->recv()) {
145     my $result = $response->content();
146     if ($result->{result} && ref($result->{result}) eq 'ARRAY') {
147         if (grep {$_->{textcode} eq 'HOLD_EXISTS'} @{$result->{result}}) {
148             $textcode = 'HOLD_EXISTS';
149         }
150     }
151 }
152 $request->finish();
153 is(
154     $textcode,
155     'HOLD_EXISTS',
156     'Got HOLD_EXISTS placing 6th title hold for patron 1'
157 );
158
159 # Place 5 holds for METARECORD_ID for PATRON1. Expect success.
160 $request = $circ_session->request(
161     'open-ils.circ.holds.test_and_create.batch',
162     $authtoken,
163     {
164         hold_type => 'M',
165         patronid => $patron1->id(),
166         pickup_lib => $patron1->home_ou()
167     },
168     [METARECORD_ID, METARECORD_ID, METARECORD_ID, METARECORD_ID, METARECORD_ID]
169 );
170 $success = 0;
171 while (my $response = $request->recv()) {
172     my $result = $response->content();
173     if ($result->{result} && !ref $result->{result}) {
174         $success++;
175         push(@holds, $result->{result});
176     }
177 }
178 $request->finish();
179 is(
180     $success,
181     5,
182     'Placed 5 metarecord holds for Patron 1'
183 );
184
185 # Place 1 hold for METARECORD_ID for PATRON1. Expect HOLD_EXISTS.
186 $request = $circ_session->request(
187     'open-ils.circ.holds.test_and_create.batch',
188     $authtoken,
189     {
190         hold_type => 'M',
191         patronid => $patron1->id(),
192         pickup_lib => $patron1->home_ou()
193     },
194     [METARECORD_ID]
195 );
196 $textcode = '';
197 while (my $response = $request->recv()) {
198     my $result = $response->content();
199     if ($result->{result} && ref($result->{result}) eq 'ARRAY') {
200         if (grep {$_->{textcode} eq 'HOLD_EXISTS'} @{$result->{result}}) {
201             $textcode = 'HOLD_EXISTS';
202         }
203     }
204 }
205 $request->finish();
206 is(
207     $textcode,
208     'HOLD_EXISTS',
209     'Got HOLD_EXISTS placing 6th metarecord hold for patron 1'
210 );
211
212 # Place 5 holds for COPY_ID for PATRON1. Expect 1 success and 4 HOLD_EXISTS.
213 $request = $circ_session->request(
214     'open-ils.circ.holds.test_and_create.batch',
215     $authtoken,
216     {
217         hold_type => 'C',
218         patronid => $patron1->id(),
219         pickup_lib => $patron1->home_ou()
220     },
221     [COPY_ID, COPY_ID, COPY_ID, COPY_ID, COPY_ID]
222 );
223 $success = 0;
224 $textcode = 0; # Using textcode as int this time.
225 while (my $response = $request->recv()) {
226     my $result = $response->content();
227     if ($result->{result} && ref($result->{result}) eq 'ARRAY') {
228         if (grep {$_->{textcode} eq 'HOLD_EXISTS'} @{$result->{result}}) {
229             $textcode++;
230         }
231     } elsif ($result->{result}) {
232         $success++;
233         push(@holds, $result->{result});
234     }
235 }
236 $request->finish();
237 is(
238     $success,
239     1,
240     'Placed 1 copy hold for patron 1'
241 );
242 is(
243     $textcode,
244     4,
245     'Got 4 HOLD_EXISTS on copy holds for patron 1'
246 );
247
248 # Retrieve PATRON2.
249 my $patron2 = $U->simplereq(
250     'open-ils.actor',
251     'open-ils.actor.user.fleshed.retrieve_by_barcode',
252     $authtoken,
253     PATRON2_BARCODE
254 );
255 isa_ok(
256     ref $patron2,
257     'Fieldmapper::actor::user',
258     'Got patron 2'
259 ) or BAIL_OUT('Need Patron 2');
260
261 # Place 5 holds for RECORD_ID for PATRON2. Expect 1 success and 4 HOLD_EXISTS.
262 $request = $circ_session->request(
263     'open-ils.circ.holds.test_and_create.batch',
264     $authtoken,
265     {
266         hold_type => 'T',
267         patronid => $patron2->id(),
268         pickup_lib => $patron2->home_ou()
269     },
270     [RECORD_ID, RECORD_ID, RECORD_ID, RECORD_ID, RECORD_ID]
271 );
272 $success = 0;
273 $textcode = 0; # Using textcode as int this time.
274 while (my $response = $request->recv()) {
275     my $result = $response->content();
276     if ($result->{result} && ref($result->{result}) eq 'ARRAY') {
277         if (grep {$_->{textcode} eq 'HOLD_EXISTS'} @{$result->{result}}) {
278             $textcode++;
279         }
280     } elsif ($result->{result}) {
281         $success++;
282         push(@holds, $result->{result});
283     }
284 }
285 $request->finish();
286 is(
287     $success,
288     1,
289     'Placed 1 title hold for patron 2'
290 );
291 is(
292     $textcode,
293     4,
294     'Got 4 HOLD_EXISTS on title holds for patron 2'
295 );
296
297 # Place 5 holds for METARECORD_ID for PATRON2. Expect 1 success and 4 HOLD_EXISTS.
298 $request = $circ_session->request(
299     'open-ils.circ.holds.test_and_create.batch',
300     $authtoken,
301     {
302         hold_type => 'M',
303         patronid => $patron2->id(),
304         pickup_lib => $patron2->home_ou()
305     },
306     [METARECORD_ID, METARECORD_ID, METARECORD_ID, METARECORD_ID, METARECORD_ID]
307 );
308 $success = 0;
309 $textcode = 0; # Using textcode as int this time.
310 while (my $response = $request->recv()) {
311     my $result = $response->content();
312     if ($result->{result} && ref($result->{result}) eq 'ARRAY') {
313         if (grep {$_->{textcode} eq 'HOLD_EXISTS'} @{$result->{result}}) {
314             $textcode++;
315         }
316     } elsif ($result->{result}) {
317         $success++;
318         push(@holds, $result->{result});
319     }
320 }
321 $request->finish();
322 is(
323     $success,
324     1,
325     'Placed 1 metarecord hold for patron 2'
326 );
327 is(
328     $textcode,
329     4,
330     'Got 4 HOLD_EXISTS on metarecord holds for patron 2'
331 );
332
333 # Place 5 holds for COPY_ID for PATRON2. Expect 1 success and 4 HOLD_EXISTS.
334 $request = $circ_session->request(
335     'open-ils.circ.holds.test_and_create.batch',
336     $authtoken,
337     {
338         hold_type => 'C',
339         patronid => $patron2->id(),
340         pickup_lib => $patron2->home_ou()
341     },
342     [COPY_ID, COPY_ID, COPY_ID, COPY_ID, COPY_ID]
343 );
344 $success = 0;
345 $textcode = 0; # Using textcode as int this time.
346 while (my $response = $request->recv()) {
347     my $result = $response->content();
348     if ($result->{result} && ref($result->{result}) eq 'ARRAY') {
349         if (grep {$_->{textcode} eq 'HOLD_EXISTS'} @{$result->{result}}) {
350             $textcode++;
351         }
352     } elsif ($result->{result}) {
353         $success++;
354         push(@holds, $result->{result});
355     }
356 }
357 $request->finish();
358 is(
359     $success,
360     1,
361     'Placed 1 copy hold for patron 2'
362 );
363 is(
364     $textcode,
365     4,
366     'Got 4 HOLD_EXISTS on copy holds for patron 2'
367 );
368
369 # Cancel all of the holds placed.
370 # How many successes we expect.
371 my $expect = scalar(@holds);
372 $success = 0;
373 foreach my $hold (@holds) {
374     my $result = $circ_session->request(
375         'open-ils.circ.hold.cancel',
376         $authtoken,
377         $hold,
378         5,
379         'LP 1694058 perl test'
380     )->gather(1);
381     if ($result && ! ref $result) {
382         $success++;
383     }
384 }
385 is(
386     $success,
387     $expect,
388     "Cancelled $expect holds"
389 );
390
391 # Reset @holds
392 @holds = ();
393
394 # Test the permission by logging in as patron 1 and placing a title and metarecord hold.
395
396 # Login as patron1.
397 my $patron_auth = $script->authenticate({
398     username => $patron1->usrname(),
399     password => 'leona1234',
400     type => 'opac'
401 });
402 ok(
403     $patron_auth,
404     'Logged in as patron 1'
405 );
406
407 # Place 5 holds for RECORD_ID as PATRON1. Expect 1 success and 4 HOLD_EXISTS.
408 $request = $circ_session->request(
409     'open-ils.circ.holds.test_and_create.batch',
410     $patron_auth,
411     {
412         hold_type => 'T',
413         patronid => $patron1->id(),
414         pickup_lib => $patron1->home_ou()
415     },
416     [RECORD_ID, RECORD_ID, RECORD_ID, RECORD_ID, RECORD_ID]
417 );
418 $success = 0;
419 $textcode = 0; # Using textcode as int this time.
420 while (my $response = $request->recv()) {
421     my $result = $response->content();
422     if ($result->{result} && ref($result->{result}) eq 'ARRAY') {
423         if (grep {$_->{textcode} eq 'HOLD_EXISTS'} @{$result->{result}}) {
424             $textcode++;
425         }
426     } elsif ($result->{result}) {
427         $success++;
428         push(@holds, $result->{result});
429     }
430 }
431 $request->finish();
432 is(
433     $success,
434     1,
435     'Patron 1 placed 1 title hold'
436 );
437 is(
438     $textcode,
439     4,
440     'Patron 1 got 4 HOLD_EXISTS on title holds'
441 );
442
443 # Ditto for metarecord holds:
444 $request = $circ_session->request(
445     'open-ils.circ.holds.test_and_create.batch',
446     $patron_auth,
447     {
448         hold_type => 'T',
449         patronid => $patron1->id(),
450         pickup_lib => $patron1->home_ou()
451     },
452     [METARECORD_ID, METARECORD_ID, METARECORD_ID, METARECORD_ID, METARECORD_ID]
453 );
454 $success = 0;
455 $textcode = 0; # Using textcode as int this time.
456 while (my $response = $request->recv()) {
457     my $result = $response->content();
458     if ($result->{result} && ref($result->{result}) eq 'ARRAY') {
459         if (grep {$_->{textcode} eq 'HOLD_EXISTS'} @{$result->{result}}) {
460             $textcode++;
461         }
462     } elsif ($result->{result}) {
463         $success++;
464         push(@holds, $result->{result});
465     }
466 }
467 $request->finish();
468 is(
469     $success,
470     1,
471     'Patron 1 placed 1 metarecord hold'
472 );
473 is(
474     $textcode,
475     4,
476     'Patron 1 got 4 HOLD_EXISTS on metarecord holds'
477 );
478
479 # Cancel the patron-placed holds.
480 $expect = scalar(@holds);
481 $success = 0;
482 foreach my $hold (@holds) {
483     my $result = $circ_session->request(
484         'open-ils.circ.hold.cancel',
485         $patron_auth,
486         $hold,
487         6,
488         'LP 1694058 perl test'
489     )->gather(1);
490     if ($result && ! ref $result) {
491         $success++;
492     }
493 }
494 is(
495     $success,
496     $expect,
497     "Cancelled $expect patron holds"
498 );
499
500 # Reset @holds
501 @holds = ();
502
503 # Unset OILS_SETTING_MAX_DUPLICATE_HOLDS at BR1.
504 $setting_value = $U->simplereq(
505     'open-ils.actor',
506     'open-ils.actor.org_unit.settings.update',
507     $authtoken,
508     BR1_ID,
509     {OILS_SETTING_MAX_DUPLICATE_HOLDS, undef}
510 );
511 ok(
512     ! ref $setting_value,
513     'circ.holds.max_duplicate_holds unset for BR1'
514 );
515
516 # Logout. Because of a "bug" in Cronscript.pm, we need to log out in the order that we logged in.
517 $script->logout($authtoken);
518 $script->logout($patron_auth);
519 ok(
520     ! $script->authtoken,
521     'Successfully logged out'
522 );
523