Line 0
Link Here
|
0 |
- |
1 |
#!/usr/bin/env perl |
|
|
2 |
|
3 |
# This file is part of Koha. |
4 |
# |
5 |
# Koha is free software; you can redistribute it and/or modify it under the |
6 |
# terms of the GNU General Public License as published by the Free Software |
7 |
# Foundation; either version 3 of the License, or (at your option) any later |
8 |
# version. |
9 |
# |
10 |
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY |
11 |
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR |
12 |
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
13 |
# |
14 |
# You should have received a copy of the GNU General Public License along |
15 |
# with Koha; if not, write to the Free Software Foundation, Inc., |
16 |
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
17 |
|
18 |
use Modern::Perl; |
19 |
|
20 |
use Test::More tests => 2; |
21 |
use Test::Mojo; |
22 |
use Test::Warn; |
23 |
|
24 |
use t::lib::TestBuilder; |
25 |
use t::lib::Mocks; |
26 |
|
27 |
use C4::Auth; |
28 |
use Koha::Biblio::Availability; |
29 |
use Koha::Item::Availability; |
30 |
use Koha::Database; |
31 |
|
32 |
require t::db_dependent::Koha::Availability::Helpers; |
33 |
|
34 |
my $schema = Koha::Database->new->schema; |
35 |
my $builder = t::lib::TestBuilder->new; |
36 |
|
37 |
# FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling |
38 |
# this affects the other REST api tests |
39 |
t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' ); |
40 |
|
41 |
my $remote_address = '127.0.0.1'; |
42 |
my $t = Test::Mojo->new('Koha::REST::V1'); |
43 |
|
44 |
subtest '/availability/biblio' => sub { |
45 |
plan tests => 2; |
46 |
|
47 |
subtest '/hold' => sub { |
48 |
plan tests => 30; |
49 |
|
50 |
$schema->storage->txn_begin; |
51 |
|
52 |
set_default_circulation_rules(); |
53 |
set_default_system_preferences(); |
54 |
|
55 |
my $item = build_a_test_item(); |
56 |
my $item2 = build_a_test_item( |
57 |
Koha::Biblios->find($item->biblionumber), |
58 |
Koha::Biblioitems->find($item->biblioitemnumber) |
59 |
); |
60 |
my ($patron, $session_id) = create_user_and_session(); |
61 |
$patron = Koha::Patrons->find($patron); |
62 |
my $route = '/api/v1/availability/biblio/hold'; |
63 |
my $tx = $t->ua->build_tx( GET => $route . '?biblionumber='.$item->biblionumber ); |
64 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
65 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
66 |
$t->request_ok($tx) |
67 |
->status_is(200) |
68 |
->json_has('/0/availability') |
69 |
->json_is('/0/availability/available' => Mojo::JSON->true) |
70 |
->json_is('/0/item_availabilities/0/availability/available' => Mojo::JSON->true) |
71 |
->json_is('/0/item_availabilities/1/availability/available' => Mojo::JSON->true); |
72 |
|
73 |
$tx = $t->ua->build_tx( GET => $route . '?biblionumber='.$item->biblionumber.'&limit_items=1' ); |
74 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
75 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
76 |
$t->request_ok($tx) |
77 |
->status_is(200) |
78 |
->json_has('/0/availability') |
79 |
->json_has('/0/item_availabilities/0') |
80 |
->json_hasnt('/0/item_availabilities/1'); |
81 |
|
82 |
$patron->gonenoaddress('1')->store; |
83 |
$item2->notforloan('1')->store; |
84 |
$tx = $t->ua->build_tx( GET => $route . '?biblionumber='.$item->biblionumber ); |
85 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
86 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
87 |
$t->request_ok($tx) |
88 |
->status_is(200) |
89 |
->json_has('/0/availability') |
90 |
->json_is('/0/availability/available' => Mojo::JSON->false) |
91 |
->json_is('/0/availability/unavailabilities/Patron::GoneNoAddress' => {}) |
92 |
->json_is('/0/item_availabilities/0/itemnumber' => $item->itemnumber) |
93 |
->json_is('/0/item_availabilities/0/availability/available' => Mojo::JSON->true) |
94 |
->json_is('/0/item_availabilities/1/itemnumber' => $item2->itemnumber) |
95 |
->json_is('/0/item_availabilities/1/availability/available' => Mojo::JSON->false) |
96 |
->json_is('/0/item_availabilities/1/availability/unavailabilities/Item::NotForLoan' => { |
97 |
code => "Not For Loan", |
98 |
status => 1, |
99 |
}); |
100 |
$patron->gonenoaddress('0')->store; |
101 |
$item2->notforloan('0')->store; |
102 |
|
103 |
my $patron2 = build_a_test_patron(); |
104 |
$tx = $t->ua->build_tx( GET => $route . '?biblionumber='.$item->biblionumber.'&borrowernumber='.$patron2->borrowernumber ); |
105 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
106 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
107 |
$t->request_ok($tx) |
108 |
->status_is(403); |
109 |
|
110 |
my $branch = Koha::Libraries->find( |
111 |
$builder->build({ source => 'Branch' })->{'branchcode'}); |
112 |
t::lib::Mocks::mock_preference('UseBranchTransferLimits', 1); |
113 |
t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'itemtype'); |
114 |
C4::Circulation::CreateBranchTransferLimit( |
115 |
$branch->branchcode, |
116 |
$item->holdingbranch, |
117 |
$item->effective_itemtype |
118 |
); |
119 |
|
120 |
$tx = $t->ua->build_tx( GET => $route . '?biblionumber='.$item->biblionumber.'&branchcode='.$branch->branchcode ); |
121 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
122 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
123 |
$t->request_ok($tx) |
124 |
->status_is(200) |
125 |
->json_has('/0/availability') |
126 |
->json_is('/0/availability/available' => Mojo::JSON->true) |
127 |
->json_is('/0/item_availabilities/0/availability/available' => Mojo::JSON->true) |
128 |
->json_is('/0/item_availabilities/1/availability/available' => Mojo::JSON->false) |
129 |
->json_is('/0/item_availabilities/1/availability/unavailabilities/Item::CannotBeTransferred' => { |
130 |
from_library => $item->holdingbranch, |
131 |
to_library => $branch->branchcode,}); |
132 |
|
133 |
$schema->storage->txn_rollback; |
134 |
}; |
135 |
|
136 |
subtest '/search' => sub { |
137 |
plan tests => 15; |
138 |
|
139 |
$schema->storage->txn_begin; |
140 |
|
141 |
set_default_circulation_rules(); |
142 |
set_default_system_preferences(); |
143 |
|
144 |
my $item = build_a_test_item(); |
145 |
my $item2 = build_a_test_item( |
146 |
Koha::Biblios->find($item->biblionumber), |
147 |
Koha::Biblioitems->find($item->biblioitemnumber) |
148 |
); |
149 |
my $route = '/api/v1/availability/biblio/search'; |
150 |
my $tx = $t->ua->build_tx( GET => $route . '?biblionumber='.$item->biblionumber ); |
151 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
152 |
$t->request_ok($tx) |
153 |
->status_is(200) |
154 |
->json_has('/0/availability') |
155 |
->json_is('/0/availability/available' => Mojo::JSON->true) |
156 |
->json_is('/0/item_availabilities/0/availability/available' => Mojo::JSON->true) |
157 |
->json_is('/0/item_availabilities/1/availability/available' => Mojo::JSON->true); |
158 |
|
159 |
$item2->notforloan('1')->store; |
160 |
$tx = $t->ua->build_tx( GET => $route . '?biblionumber='.$item->biblionumber ); |
161 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
162 |
$t->request_ok($tx) |
163 |
->status_is(200) |
164 |
->json_has('/0/availability') |
165 |
->json_is('/0/availability/available' => Mojo::JSON->true) |
166 |
->json_is('/0/item_availabilities/0/itemnumber' => $item->itemnumber) |
167 |
->json_is('/0/item_availabilities/0/availability/available' => Mojo::JSON->true) |
168 |
->json_is('/0/item_availabilities/1/itemnumber' => $item2->itemnumber) |
169 |
->json_is('/0/item_availabilities/1/availability/available' => Mojo::JSON->false) |
170 |
->json_is('/0/item_availabilities/1/availability/unavailabilities/Item::NotForLoan' => { |
171 |
code => "Not For Loan", |
172 |
status => 1, |
173 |
}); |
174 |
|
175 |
$schema->storage->txn_rollback; |
176 |
}; |
177 |
}; |
178 |
|
179 |
subtest '/availability/item' => sub { |
180 |
plan tests => 3; |
181 |
|
182 |
subtest '/hold' => sub { |
183 |
plan tests => 17; |
184 |
|
185 |
$schema->storage->txn_begin; |
186 |
|
187 |
set_default_circulation_rules(); |
188 |
set_default_system_preferences(); |
189 |
|
190 |
my $item = build_a_test_item(); |
191 |
my ($patron, $session_id) = create_user_and_session(); |
192 |
$patron = Koha::Patrons->find($patron); |
193 |
my $route = '/api/v1/availability/item/hold'; |
194 |
my $tx = $t->ua->build_tx( GET => $route . '?itemnumber='.$item->itemnumber ); |
195 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
196 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
197 |
$t->request_ok($tx) |
198 |
->status_is(200) |
199 |
->json_has('/0/availability') |
200 |
->json_is('/0/availability/available' => Mojo::JSON->true); |
201 |
|
202 |
$patron->gonenoaddress('1')->store; |
203 |
$item->notforloan('1')->store; |
204 |
$tx = $t->ua->build_tx( GET => $route . '?itemnumber='.$item->itemnumber ); |
205 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
206 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
207 |
$t->request_ok($tx) |
208 |
->status_is(200) |
209 |
->json_has('/0/availability') |
210 |
->json_is('/0/availability/available' => Mojo::JSON->false) |
211 |
->json_is('/0/itemnumber' => $item->itemnumber) |
212 |
->json_is('/0/availability/unavailabilities/Patron::GoneNoAddress' => {}) |
213 |
->json_is('/0/availability/unavailabilities/Item::NotForLoan' => { |
214 |
code => "Not For Loan", |
215 |
status => 1, |
216 |
}); |
217 |
$patron->gonenoaddress('0')->store; |
218 |
$item->notforloan('0')->store; |
219 |
|
220 |
my $patron2 = build_a_test_patron(); |
221 |
$tx = $t->ua->build_tx( GET => $route . '?itemnumber='.$item->itemnumber.'&borrowernumber='.$patron2->borrowernumber ); |
222 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
223 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
224 |
$t->request_ok($tx) |
225 |
->status_is(403); |
226 |
|
227 |
my $branch = Koha::Libraries->find( |
228 |
$builder->build({ source => 'Branch' })->{'branchcode'}); |
229 |
t::lib::Mocks::mock_preference('UseBranchTransferLimits', 1); |
230 |
t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'itemtype'); |
231 |
C4::Circulation::CreateBranchTransferLimit( |
232 |
$branch->branchcode, |
233 |
$item->holdingbranch, |
234 |
$item->effective_itemtype |
235 |
); |
236 |
|
237 |
$tx = $t->ua->build_tx( GET => $route . '?itemnumber='.$item->itemnumber.'&branchcode='.$branch->branchcode ); |
238 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
239 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
240 |
$t->request_ok($tx) |
241 |
->status_is(200) |
242 |
->json_is('/0/availability/available' => Mojo::JSON->false) |
243 |
->json_is('/0/availability/unavailabilities/Item::CannotBeTransferred' => { |
244 |
from_library => $item->holdingbranch, |
245 |
to_library => $branch->branchcode,}); |
246 |
|
247 |
$schema->storage->txn_rollback; |
248 |
}; |
249 |
|
250 |
subtest '/checkout' => sub { |
251 |
plan tests => 12; |
252 |
|
253 |
$schema->storage->txn_begin; |
254 |
|
255 |
set_default_circulation_rules(); |
256 |
set_default_system_preferences(); |
257 |
|
258 |
my $item = build_a_test_item(); |
259 |
my ($patron, $session_id) = create_user_and_session(); |
260 |
$patron = Koha::Patrons->find($patron); |
261 |
my $route = '/api/v1/availability/item/checkout'; |
262 |
my $tx = $t->ua->build_tx( GET => $route . '?itemnumber='.$item->itemnumber ); |
263 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
264 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
265 |
$t->request_ok($tx) |
266 |
->status_is(200) |
267 |
->json_has('/0/availability') |
268 |
->json_is('/0/availability/available' => Mojo::JSON->true); |
269 |
|
270 |
$item->notforloan('1')->store; |
271 |
$tx = $t->ua->build_tx( GET => $route . '?itemnumber='.$item->itemnumber ); |
272 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
273 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
274 |
$t->request_ok($tx) |
275 |
->status_is(200) |
276 |
->json_has('/0/availability') |
277 |
->json_is('/0/availability/available' => Mojo::JSON->false) |
278 |
->json_is('/0/itemnumber' => $item->itemnumber) |
279 |
->json_is('/0/availability/unavailabilities/Item::NotForLoan' => { |
280 |
code => "Not For Loan", |
281 |
status => 1, |
282 |
}); |
283 |
$item->notforloan('0')->store; |
284 |
|
285 |
my $patron2 = build_a_test_patron(); |
286 |
$tx = $t->ua->build_tx( GET => $route . '?itemnumber='.$item->itemnumber.'&borrowernumber='.$patron2->borrowernumber ); |
287 |
$tx->req->cookies( { name => 'CGISESSID', value => $session_id } ); |
288 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
289 |
$t->request_ok($tx) |
290 |
->status_is(403); |
291 |
|
292 |
$schema->storage->txn_rollback; |
293 |
}; |
294 |
|
295 |
subtest '/search' => sub { |
296 |
plan tests => 15; |
297 |
|
298 |
$schema->storage->txn_begin; |
299 |
|
300 |
set_default_circulation_rules(); |
301 |
set_default_system_preferences(); |
302 |
|
303 |
my $item = build_a_test_item(); |
304 |
my $item2 = build_a_test_item( |
305 |
Koha::Biblios->find($item->biblionumber), |
306 |
Koha::Biblioitems->find($item->biblioitemnumber) |
307 |
); |
308 |
my $route = '/api/v1/availability/biblio/search'; |
309 |
my $tx = $t->ua->build_tx( GET => $route . '?biblionumber='.$item->biblionumber ); |
310 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
311 |
$t->request_ok($tx) |
312 |
->status_is(200) |
313 |
->json_has('/0/availability') |
314 |
->json_is('/0/availability/available' => Mojo::JSON->true) |
315 |
->json_is('/0/item_availabilities/0/availability/available' => Mojo::JSON->true) |
316 |
->json_is('/0/item_availabilities/1/availability/available' => Mojo::JSON->true); |
317 |
|
318 |
$item2->notforloan('1')->store; |
319 |
$tx = $t->ua->build_tx( GET => $route . '?biblionumber='.$item->biblionumber ); |
320 |
$tx->req->env( { REMOTE_ADDR => $remote_address } ); |
321 |
$t->request_ok($tx) |
322 |
->status_is(200) |
323 |
->json_has('/0/availability') |
324 |
->json_is('/0/availability/available' => Mojo::JSON->true) |
325 |
->json_is('/0/item_availabilities/0/itemnumber' => $item->itemnumber) |
326 |
->json_is('/0/item_availabilities/0/availability/available' => Mojo::JSON->true) |
327 |
->json_is('/0/item_availabilities/1/itemnumber' => $item2->itemnumber) |
328 |
->json_is('/0/item_availabilities/1/availability/available' => Mojo::JSON->false) |
329 |
->json_is('/0/item_availabilities/1/availability/unavailabilities/Item::NotForLoan' => { |
330 |
code => "Not For Loan", |
331 |
status => 1, |
332 |
}); |
333 |
|
334 |
$schema->storage->txn_rollback; |
335 |
}; |
336 |
}; |
337 |
|
338 |
sub create_user_and_session { |
339 |
|
340 |
my $args = shift; |
341 |
my $flags = ( $args->{authorized} ) ? $args->{authorized} : 0; |
342 |
my $dbh = C4::Context->dbh; |
343 |
|
344 |
my $user = $builder->build( |
345 |
{ |
346 |
source => 'Borrower', |
347 |
value => { |
348 |
flags => $flags, |
349 |
debarred => undef, |
350 |
debarredcomment => undef, |
351 |
lost => undef, |
352 |
gonenoaddress => undef, |
353 |
dateexpiry => output_pref({ dt => dt_from_string()->add_duration( # expires in 100 days |
354 |
DateTime::Duration->new(days => 100)), dateformat => 'iso', dateonly => 1 }), |
355 |
dateofbirth => '1950-10-10', |
356 |
} |
357 |
} |
358 |
); |
359 |
|
360 |
# Create a session for the authorized user |
361 |
my $session = C4::Auth::get_session(''); |
362 |
$session->param( 'number', $user->{borrowernumber} ); |
363 |
$session->param( 'id', $user->{userid} ); |
364 |
$session->param( 'ip', '127.0.0.1' ); |
365 |
$session->param( 'lasttime', time() ); |
366 |
$session->flush; |
367 |
|
368 |
if ( $args->{authorized} ) { |
369 |
$dbh->do( " |
370 |
INSERT INTO user_permissions (borrowernumber,module_bit,code) |
371 |
VALUES (?,3,'parameters_remaining_permissions')", undef, |
372 |
$user->{borrowernumber} ); |
373 |
} |
374 |
|
375 |
return ( $user->{borrowernumber}, $session->id ); |
376 |
} |
377 |
|
378 |
1; |