Line 0
Link Here
|
0 |
- |
1 |
#!/usr/bin/perl |
|
|
2 |
|
3 |
# This file is part of Koha. |
4 |
# |
5 |
# Koha is free software; you can redistribute it and/or modify it |
6 |
# under the terms of the GNU General Public License as published by |
7 |
# the Free Software Foundation; either version 3 of the License, or |
8 |
# (at your option) any later version. |
9 |
# |
10 |
# Koha is distributed in the hope that it will be useful, but |
11 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
# GNU General Public License for more details. |
14 |
# |
15 |
# You should have received a copy of the GNU General Public License |
16 |
# along with Koha; if not, see <http://www.gnu.org/licenses>. |
17 |
|
18 |
use Modern::Perl; |
19 |
use Test::More tests => 2; |
20 |
|
21 |
use C4::Biblio qw(DelBiblio); |
22 |
|
23 |
use C4::Context; |
24 |
use Koha::AuthUtils; |
25 |
use t::lib::Mocks; |
26 |
use t::lib::Selenium; |
27 |
use t::lib::TestBuilder; |
28 |
|
29 |
our $builder = t::lib::TestBuilder->new; |
30 |
|
31 |
our $biblio_title = 'opac holds test place hold button'; |
32 |
our $biblio_title_search = $biblio_title =~ s/\s/+/gr; |
33 |
our $biblio = $builder->build_sample_biblio( { title => $biblio_title } ); |
34 |
our $second_biblio = $builder->build_sample_biblio( { title => $biblio_title } ); |
35 |
|
36 |
our $biblionumber = $biblio->biblionumber; |
37 |
our $second_biblionumber = $second_biblio->biblionumber; |
38 |
|
39 |
our $item_1 = $builder->build_sample_item( |
40 |
{ |
41 |
biblionumber => $biblio->biblionumber, |
42 |
} |
43 |
); |
44 |
our $item_1_itemnumber = $item_1->itemnumber; |
45 |
|
46 |
our $item_2 = $builder->build_sample_item( |
47 |
{ |
48 |
biblionumber => $biblio->biblionumber, |
49 |
} |
50 |
); |
51 |
our $item_2_itemnumber = $item_2->itemnumber; |
52 |
|
53 |
our $item_3 = $builder->build_sample_item( |
54 |
{ |
55 |
biblionumber => $second_biblio->biblionumber, |
56 |
} |
57 |
); |
58 |
our $item_3_itemnumber = $item_3->itemnumber; |
59 |
|
60 |
our $item_4 = $builder->build_sample_item( |
61 |
{ |
62 |
biblionumber => $second_biblio->biblionumber, |
63 |
} |
64 |
); |
65 |
our $item_4_itemnumber = $item_4->itemnumber; |
66 |
|
67 |
# Selenium is faster than search indexer, it needs to wait |
68 |
sleep 10; |
69 |
|
70 |
SKIP: { |
71 |
eval { require Selenium::Remote::Driver; }; |
72 |
skip "Selenium::Remote::Driver is needed for selenium tests.", 3 if $@; |
73 |
|
74 |
our $s = t::lib::Selenium->new; |
75 |
our $driver = $s->driver; |
76 |
|
77 |
subtest 'not authenticated' => sub { |
78 |
plan tests => 2; |
79 |
|
80 |
reset_data(); |
81 |
|
82 |
subtest 'search results' => sub { |
83 |
plan tests => 7; |
84 |
|
85 |
# 'Place hold' button exists by default |
86 |
$driver->get( $s->opac_base_url . "opac-search.pl?q=" . $biblio_title_search ); |
87 |
like( |
88 |
$driver->get_title, qr(Results of search for '$biblio_title'), |
89 |
'Correctly in search results page' |
90 |
); |
91 |
|
92 |
is( |
93 |
$driver->find_element('//div[@class="actions-menu noprint"]/span[@class="actions"]/a')->get_text, |
94 |
'Place hold', |
95 |
'Place hold button should be present', |
96 |
); |
97 |
|
98 |
# 'Place hold' button doesn't exist when holds are not allowed |
99 |
set_holdallowed_not_allowed(); |
100 |
search_page_hold_button_absent('Unauthenticated - holdallowed not allowed'); |
101 |
reset_data(); |
102 |
|
103 |
# 'Place hold' button doesn't exist when all items are withdrawn |
104 |
withdraw_items(); |
105 |
search_page_hold_button_absent('Unauthenticated - Items withdrawn'); |
106 |
reset_data(); |
107 |
|
108 |
# Set onshelfholds rule |
109 |
# 0 - "If any unavailable" |
110 |
# 1 - "Yes" |
111 |
# 2 - "If all unavailable" |
112 |
|
113 |
# Always shows "Place hold" for unauthenticated because onshelfholds is not considered |
114 |
set_onshelfholds(0); |
115 |
search_page_hold_button_present('Unauthenticated - onshelfholds If any unavailable'); |
116 |
reset_data(); |
117 |
|
118 |
# Always shows "Place hold" for unauthenticated because onshelfholds is not considered |
119 |
set_onshelfholds(1); |
120 |
search_page_hold_button_present('Unauthenticated - onshelfholds Yes'); |
121 |
reset_data(); |
122 |
|
123 |
# Always shows "Place hold" for unauthenticated because onshelfholds is not considered |
124 |
set_onshelfholds(2); |
125 |
search_page_hold_button_present('Unauthenticated - onshelfholds If all unavailable'); |
126 |
reset_data(); |
127 |
}; |
128 |
|
129 |
subtest 'detail page' => sub { |
130 |
plan tests => 7; |
131 |
|
132 |
# 'Place hold' button exists by default |
133 |
$driver->get( $s->opac_base_url . "opac-detail.pl?biblionumber=" . $biblionumber ); |
134 |
like( |
135 |
$driver->get_title, qr(Details for: $biblio_title), |
136 |
'Correctly in detail page' |
137 |
); |
138 |
|
139 |
is( |
140 |
$driver->find_element('//div[@id="ulactioncontainer"]/ul[@id="action"]/li/a')->get_text, |
141 |
'Place hold', |
142 |
'Place hold button should be present', |
143 |
); |
144 |
|
145 |
# 'Place hold' button doesn't exist when holds are not allowed |
146 |
set_holdallowed_not_allowed(); |
147 |
detail_page_hold_button_absent('Unauthenticated - holdallowed not allowed'); |
148 |
reset_data(); |
149 |
|
150 |
# 'Place hold' button doesn't exist when all items are withdrawn |
151 |
withdraw_items(); |
152 |
detail_page_hold_button_absent('Unauthenticated - items withdrawn'); |
153 |
reset_data(); |
154 |
|
155 |
# Set onshelfholds rule |
156 |
# 0 - "If any unavailable" |
157 |
# 1 - "Yes" |
158 |
# 2 - "If all unavailable" |
159 |
|
160 |
# Always shows "Place hold" for unauthenticated because onshelfholds is not considered |
161 |
set_onshelfholds(0); |
162 |
detail_page_hold_button_present('Unauthenticated - onshelfholds If any unavailable'); |
163 |
reset_data(); |
164 |
|
165 |
# Always shows "Place hold" for unauthenticated because onshelfholds is not considered |
166 |
set_onshelfholds(1); |
167 |
detail_page_hold_button_present('Unauthenticated - onshelfholds Yes'); |
168 |
reset_data(); |
169 |
|
170 |
# Always shows "Place hold" for unauthenticated because onshelfholds is not considered |
171 |
set_onshelfholds(2); |
172 |
detail_page_hold_button_present('Unauthenticated - onshelfholds If all unavailable'); |
173 |
reset_data(); |
174 |
}; |
175 |
|
176 |
}; |
177 |
|
178 |
subtest 'authenticated' => sub { |
179 |
plan tests => 5; |
180 |
|
181 |
my $mainpage = $s->opac_base_url . q|opac-main.pl|; |
182 |
|
183 |
$driver->get( $mainpage . q|?logout.x=1| ) |
184 |
; # Disconnect first! We are logged in if staff and opac interfaces are separated by ports |
185 |
|
186 |
$driver->get($mainpage); |
187 |
like( |
188 |
$driver->get_title, qr(Koha online catalog), |
189 |
'Hitting the main page should not redirect to the login form' |
190 |
); |
191 |
|
192 |
my $patron = $builder->build_object( { class => 'Koha::Patrons', value => { flags => 0 } } ); |
193 |
my $password = Koha::AuthUtils::generate_password( $patron->category ); |
194 |
t::lib::Mocks::mock_preference( 'RequireStrongPassword', 0 ); |
195 |
$patron->set_password( { password => $password } ); |
196 |
|
197 |
# Using the modal |
198 |
$driver->find_element('//a[@class="nav-link login-link loginModal-trigger"]')->click; |
199 |
$s->fill_form( { muserid => $patron->userid, mpassword => $password } ); |
200 |
$driver->find_element('//div[@id="loginModal"]//input[@type="submit"]')->click; |
201 |
like( |
202 |
$driver->get_title, qr(Koha online catalog), |
203 |
'Patron without permission should be able to login to the OPAC using the modal' |
204 |
); |
205 |
$driver->find_element('//div[@id="userdetails"]'); |
206 |
like( |
207 |
$driver->get_title, qr(Your library home), |
208 |
'Patron without permissions should be able to login to the OPAC using the modal' |
209 |
); |
210 |
|
211 |
reset_data(); |
212 |
|
213 |
subtest 'search results' => sub { |
214 |
plan tests => 7; |
215 |
|
216 |
# 'Place hold' button exists by default |
217 |
$driver->get( $s->opac_base_url . "opac-search.pl?q=" . $biblio_title_search ); |
218 |
like( |
219 |
$driver->get_title, qr(Results of search for '$biblio_title'), |
220 |
'Correctly in search results page' |
221 |
); |
222 |
|
223 |
is( |
224 |
$driver->find_element('//div[@class="actions-menu noprint"]/span[@class="actions"]/a')->get_text, |
225 |
'Place hold', |
226 |
'Place hold button should be present', |
227 |
); |
228 |
|
229 |
# 'Place hold' button doesn't exist when holds are not allowed |
230 |
set_holdallowed_not_allowed(); |
231 |
search_page_hold_button_absent('Authenticated - holdallowed not allowed'); |
232 |
reset_data(); |
233 |
|
234 |
# 'Place hold' button doesn't exist when all items are withdrawn |
235 |
withdraw_items(); |
236 |
search_page_hold_button_absent('Authenticated - items withdrawn'); |
237 |
reset_data(); |
238 |
|
239 |
# Set onshelfholds rule |
240 |
# 0 - "If any unavailable" |
241 |
# 1 - "Yes" |
242 |
# 2 - "If all unavailable" |
243 |
|
244 |
# 'Place hold' button doesn't exist because all are available |
245 |
set_onshelfholds(0); |
246 |
search_page_hold_button_absent('Authenticated - onshelfholds If any unavailable'); |
247 |
reset_data(); |
248 |
|
249 |
set_onshelfholds(1); |
250 |
search_page_hold_button_present('Authenticated - onshelfholds Yes'); |
251 |
reset_data(); |
252 |
|
253 |
# 'Place hold' button doesn't exist because all are available |
254 |
set_onshelfholds(2); |
255 |
search_page_hold_button_absent('Authenticated - onshelfholds If all unavailable'); |
256 |
reset_data(); |
257 |
}; |
258 |
|
259 |
subtest 'detail page' => sub { |
260 |
plan tests => 7; |
261 |
|
262 |
# 'Place hold' button exists by default |
263 |
$driver->get( $s->opac_base_url . "opac-detail.pl?biblionumber=" . $biblionumber ); |
264 |
like( |
265 |
$driver->get_title, qr(Details for: $biblio_title), |
266 |
'Correctly in detail page' |
267 |
); |
268 |
|
269 |
is( |
270 |
$driver->find_element('//div[@id="ulactioncontainer"]/ul[@id="action"]/li/a')->get_text, |
271 |
'Place hold', |
272 |
'Place hold button should be present', |
273 |
); |
274 |
|
275 |
# 'Place hold' button exists even though holdallowed = not_allowed |
276 |
# because it's using category based circulation rules instead |
277 |
set_holdallowed_not_allowed(); |
278 |
detail_page_hold_button_present('Authenticated - holdallowed not allowed'); |
279 |
reset_data(); |
280 |
|
281 |
# 'Place hold' button doesn't exist when all items are withdrawn |
282 |
withdraw_items(); |
283 |
detail_page_hold_button_absent('Authenticated - items withdrawn'); |
284 |
reset_data(); |
285 |
|
286 |
# Set onshelfholds rule |
287 |
# 0 - "If any unavailable" |
288 |
# 1 - "Yes" |
289 |
# 2 - "If all unavailable" |
290 |
|
291 |
# 'Place hold' button doesn't exist because all are available |
292 |
set_onshelfholds(0); |
293 |
detail_page_hold_button_absent('Authenticated - onshelfholds If any unavailable'); |
294 |
reset_data(); |
295 |
|
296 |
set_onshelfholds(1); |
297 |
detail_page_hold_button_present('Authenticated - onshelfholds Yes'); |
298 |
reset_data(); |
299 |
|
300 |
# 'Place hold' button doesn't exist because all are available |
301 |
set_onshelfholds(2); |
302 |
detail_page_hold_button_absent('Authenticated - onshelfholds If all unavailable'); |
303 |
reset_data(); |
304 |
}; |
305 |
|
306 |
}; |
307 |
|
308 |
$driver->quit(); |
309 |
|
310 |
sub reset_data { |
311 |
my $dbh = C4::Context->dbh; |
312 |
$dbh->do(q|DELETE FROM circulation_rules WHERE rule_name="holdallowed"|); |
313 |
$dbh->do(q|UPDATE circulation_rules SET rule_value=1 WHERE rule_name="onshelfholds"|); |
314 |
$dbh->do( |
315 |
qq|UPDATE items SET withdrawn=0 WHERE itemnumber IN ('$item_1_itemnumber','$item_2_itemnumber','$item_3_itemnumber','$item_4_itemnumber')| |
316 |
); |
317 |
} |
318 |
|
319 |
sub cleanup_data { |
320 |
my $dbh = C4::Context->dbh; |
321 |
$dbh->do( |
322 |
qq|DELETE items FROM biblio INNER JOIN items ON biblio.biblionumber = items.biblionumber WHERE biblio.title = "$biblio_title"| |
323 |
); |
324 |
DelBiblio($biblionumber); |
325 |
DelBiblio($second_biblionumber); |
326 |
} |
327 |
|
328 |
=head3 withdraw_items |
329 |
|
330 |
Withdraws items by setting their 'withdrawn' flag to 1. |
331 |
|
332 |
=cut |
333 |
|
334 |
sub withdraw_items { |
335 |
my $dbh = C4::Context->dbh; |
336 |
$dbh->do( |
337 |
qq|UPDATE items SET withdrawn=1 WHERE itemnumber IN ('$item_1_itemnumber','$item_2_itemnumber','$item_3_itemnumber','$item_4_itemnumber')| |
338 |
); |
339 |
} |
340 |
|
341 |
=head3 set_holdallowed_not_allowed |
342 |
|
343 |
Set holdallowed as not_allowed in the circulation rules |
344 |
|
345 |
=cut |
346 |
|
347 |
sub set_holdallowed_not_allowed { |
348 |
Koha::CirculationRules->set_rules( |
349 |
{ |
350 |
itemtype => undef, |
351 |
branchcode => undef, |
352 |
rules => { |
353 |
holdallowed => "not_allowed", |
354 |
} |
355 |
} |
356 |
); |
357 |
} |
358 |
|
359 |
=head3 set_onshelfholds |
360 |
|
361 |
Set holdallowed as not_allowed in the circulation rules |
362 |
0 - "If any unavailable" |
363 |
1 - "Yes" |
364 |
2 - "If all unavailable" |
365 |
|
366 |
=cut |
367 |
|
368 |
sub set_onshelfholds { |
369 |
my ($rule_value) = @_; |
370 |
Koha::CirculationRules->set_rule( |
371 |
{ |
372 |
categorycode => undef, |
373 |
itemtype => undef, |
374 |
branchcode => undef, |
375 |
rule_name => 'onshelfholds', |
376 |
rule_value => $rule_value, |
377 |
} |
378 |
); |
379 |
} |
380 |
|
381 |
=head3 search_page_hold_button_absent |
382 |
|
383 |
Function to visit search results and test for the absence of place hold buttons |
384 |
|
385 |
=cut |
386 |
|
387 |
sub search_page_hold_button_absent { |
388 |
my ($message) = @_; |
389 |
|
390 |
$driver->get( $s->opac_base_url . "opac-search.pl?q=" . $biblio_title_search ); |
391 |
|
392 |
my $place_hold_buttons = |
393 |
$driver->find_elements( '//div[@id="title_summary_' |
394 |
. $biblionumber |
395 |
. '"]/div[@class="actions-menu noprint"]/span[@class="actions"]/a[not(contains(@class,"addtoshelf"))]' |
396 |
); |
397 |
|
398 |
is( |
399 |
scalar @{$place_hold_buttons}, |
400 |
0, |
401 |
'Search page - Place hold button should be absent. ' . $message, |
402 |
); |
403 |
} |
404 |
|
405 |
=head3 search_page_hold_button_present |
406 |
|
407 |
Function to visit search results and test for the presence of place hold buttons |
408 |
|
409 |
=cut |
410 |
|
411 |
sub search_page_hold_button_present { |
412 |
my ($message) = @_; |
413 |
|
414 |
$driver->get( $s->opac_base_url . "opac-search.pl?q=" . $biblio_title_search ); |
415 |
|
416 |
is( |
417 |
$driver->find_element( |
418 |
'//div[@id="title_summary_' |
419 |
. $biblionumber |
420 |
. '"]/div[@class="actions-menu noprint"]/span[@class="actions"]/a[not(contains(@class,"addtoshelf"))]' |
421 |
)->get_text, |
422 |
'Place hold', |
423 |
'Search page - Place hold button should be present. ' . $message |
424 |
); |
425 |
} |
426 |
|
427 |
=head3 detail_page_hold_button_absent |
428 |
|
429 |
Visits the detail page and tests the absence of the place hold button |
430 |
|
431 |
=cut |
432 |
|
433 |
sub detail_page_hold_button_absent { |
434 |
my ($message) = @_; |
435 |
$driver->get( $s->opac_base_url . "opac-detail.pl?biblionumber=" . $biblionumber ); |
436 |
|
437 |
is( |
438 |
$driver->find_element('//div[@id="ulactioncontainer"]/ul[@id="action"]/li/a')->get_text, |
439 |
'Print', |
440 |
'Detail page - Place hold button should be absent. ' . $message, |
441 |
); |
442 |
} |
443 |
|
444 |
=head3 detail_page_hold_button_present |
445 |
|
446 |
Visits the detail page and tests the presence of the place hold button |
447 |
|
448 |
=cut |
449 |
|
450 |
sub detail_page_hold_button_present { |
451 |
my ($message) = @_; |
452 |
$driver->get( $s->opac_base_url . "opac-detail.pl?biblionumber=" . $biblionumber ); |
453 |
|
454 |
is( |
455 |
$driver->find_element('//div[@id="ulactioncontainer"]/ul[@id="action"]/li/a')->get_text, |
456 |
'Place hold', |
457 |
'Detail page - Place hold button should be present. ' . $message, |
458 |
); |
459 |
} |
460 |
|
461 |
} |
462 |
|
463 |
END { |
464 |
cleanup_data(); |
465 |
} |