|
Lines 24-38
my $original_PatronsPerPage = C4::Context->preference('PatronsPerPage
Link Here
|
| 24 |
our @cleanup; |
24 |
our @cleanup; |
| 25 |
our $DT_delay = 1; |
25 |
our $DT_delay = 1; |
| 26 |
|
26 |
|
| 27 |
END { |
|
|
| 28 |
unless ( @cleanup ) { say "WARNING: Cleanup failed!" } |
| 29 |
C4::Context->set_preference( 'dateformat', $original_dateformat ); |
| 30 |
C4::Context->set_preference( 'DefaultPatronSearchFields', $original_DefaultPatronSearchFields ); |
| 31 |
C4::Context->set_preference( 'DefaultPatronSearchMethod', $original_DefaultPatronSearchMethod ); |
| 32 |
C4::Context->set_preference( 'PatronsPerPage', $original_PatronsPerPage ); |
| 33 |
$_->delete for @cleanup; |
| 34 |
}; |
| 35 |
|
| 36 |
use C4::Context; |
27 |
use C4::Context; |
| 37 |
|
28 |
|
| 38 |
use utf8; |
29 |
use utf8; |
|
Lines 50-56
eval { require Selenium::Remote::Driver; };
Link Here
|
| 50 |
if ( $@ ) { |
41 |
if ( $@ ) { |
| 51 |
plan skip_all => "Selenium::Remote::Driver is needed for selenium tests."; |
42 |
plan skip_all => "Selenium::Remote::Driver is needed for selenium tests."; |
| 52 |
} else { |
43 |
} else { |
| 53 |
plan tests => 1; |
44 |
plan tests => 2; |
| 54 |
} |
45 |
} |
| 55 |
|
46 |
|
| 56 |
my $s = t::lib::Selenium->new; |
47 |
my $s = t::lib::Selenium->new; |
|
Lines 60-78
my $base_url = $s->base_url;
Link Here
|
| 60 |
my $builder = t::lib::TestBuilder->new; |
51 |
my $builder = t::lib::TestBuilder->new; |
| 61 |
my $schema = Koha::Database->schema; |
52 |
my $schema = Koha::Database->schema; |
| 62 |
|
53 |
|
| 63 |
subtest 'Search patrons' => sub { |
|
|
| 64 |
plan tests => 27; |
| 65 |
|
54 |
|
| 66 |
if ( Koha::Patrons->search({surname => {-like => "test_patron_%"}})->count ) { |
55 |
if ( Koha::Patrons->search({surname => {-like => "test_patron_%"}})->count ) { |
| 67 |
BAIL_OUT("Cannot run this test, data we need to create already exist in the DB"); |
56 |
BAIL_OUT("Cannot run this test, data we need to create already exist in the DB"); |
| 68 |
} |
57 |
} |
| 69 |
my @patrons; |
58 |
|
| 70 |
my $borrowernotes = q|<strong>just 'a" note</strong> \123 ❤|; |
59 |
my $PatronsPerPage = 15; |
| 71 |
my $borrowernotes_displayed = q|just 'a" note \123 ❤|; |
60 |
my $borrowernotes = q|<strong>just 'a" note</strong> \123 ❤|; |
| 72 |
my $branchname = q|<strong>just 'another" library</strong> \123 ❤|; |
61 |
my $borrowernotes_displayed = q|just 'a" note \123 ❤|; |
| 73 |
my $firstname = q|<strong>fir's"tname</strong> \123 ❤|; |
62 |
my $branchname = q|<strong>just 'another" library</strong> \123 ❤|; |
| 74 |
my $address = q|<strong>add'res"s</strong> \123 ❤|; |
63 |
my $firstname = q|<strong>fir's"tname</strong> \123 ❤|; |
| 75 |
my $email = q|a<strong>bad_email</strong>@example\123 ❤.com|; |
64 |
my $address = q|<strong>add'res"s</strong> \123 ❤|; |
|
|
65 |
my $email = q|a<strong>bad_email</strong>@example\123 ❤.com|; |
| 66 |
my ($attribute_type, $attribute_type_searchable, $attribute_type_searchable_not_default); |
| 67 |
sub setup { |
| 76 |
my $patron_category = $builder->build_object( |
68 |
my $patron_category = $builder->build_object( |
| 77 |
{ |
69 |
{ |
| 78 |
class => 'Koha::Patron::Categories', |
70 |
class => 'Koha::Patron::Categories', |
|
Lines 86-91
subtest 'Search patrons' => sub {
Link Here
|
| 86 |
); |
78 |
); |
| 87 |
push @cleanup, $library; |
79 |
push @cleanup, $library; |
| 88 |
|
80 |
|
|
|
81 |
my @patrons; |
| 89 |
for my $i ( 1 .. 25 ) { |
82 |
for my $i ( 1 .. 25 ) { |
| 90 |
push @patrons, |
83 |
push @patrons, |
| 91 |
$builder->build_object( |
84 |
$builder->build_object( |
|
Lines 144-150
subtest 'Search patrons' => sub {
Link Here
|
| 144 |
); |
137 |
); |
| 145 |
unshift @cleanup, $patron_27; |
138 |
unshift @cleanup, $patron_27; |
| 146 |
|
139 |
|
| 147 |
my $attribute_type = Koha::Patron::Attribute::Type->new( |
140 |
$attribute_type = Koha::Patron::Attribute::Type->new( |
| 148 |
{ |
141 |
{ |
| 149 |
code => 'my code1', |
142 |
code => 'my code1', |
| 150 |
description => 'my description1', |
143 |
description => 'my description1', |
|
Lines 152-158
subtest 'Search patrons' => sub {
Link Here
|
| 152 |
searched_by_default => 0 |
145 |
searched_by_default => 0 |
| 153 |
} |
146 |
} |
| 154 |
)->store; |
147 |
)->store; |
| 155 |
my $attribute_type_searchable = Koha::Patron::Attribute::Type->new( |
148 |
$attribute_type_searchable = Koha::Patron::Attribute::Type->new( |
| 156 |
{ |
149 |
{ |
| 157 |
code => 'my code2', |
150 |
code => 'my code2', |
| 158 |
description => 'my description2', |
151 |
description => 'my description2', |
|
Lines 161-167
subtest 'Search patrons' => sub {
Link Here
|
| 161 |
searched_by_default => 1 |
154 |
searched_by_default => 1 |
| 162 |
} |
155 |
} |
| 163 |
)->store; |
156 |
)->store; |
| 164 |
my $attribute_type_searchable_not_default = Koha::Patron::Attribute::Type->new( |
157 |
$attribute_type_searchable_not_default = Koha::Patron::Attribute::Type->new( |
| 165 |
{ |
158 |
{ |
| 166 |
code => 'mycode3', |
159 |
code => 'mycode3', |
| 167 |
description => 'my description3', |
160 |
description => 'my description3', |
|
Lines 182-188
subtest 'Search patrons' => sub {
Link Here
|
| 182 |
{ code => $attribute_type_searchable->code, attribute => 'test_attr_2'}, |
175 |
{ code => $attribute_type_searchable->code, attribute => 'test_attr_2'}, |
| 183 |
{ code => $attribute_type_searchable_not_default->code, attribute => 'test_attr_3'}, |
176 |
{ code => $attribute_type_searchable_not_default->code, attribute => 'test_attr_3'}, |
| 184 |
]); |
177 |
]); |
|
|
178 |
C4::Context->set_preference('PatronsPerPage', $PatronsPerPage); |
| 179 |
} |
| 185 |
|
180 |
|
|
|
181 |
sub teardown { |
| 182 |
C4::Context->set_preference( 'dateformat', $original_dateformat ); |
| 183 |
C4::Context->set_preference( 'DefaultPatronSearchFields', $original_DefaultPatronSearchFields ); |
| 184 |
C4::Context->set_preference( 'DefaultPatronSearchMethod', $original_DefaultPatronSearchMethod ); |
| 185 |
C4::Context->set_preference( 'PatronsPerPage', $original_PatronsPerPage ); |
| 186 |
$_->delete for @cleanup; |
| 187 |
@cleanup = (); |
| 188 |
} |
| 189 |
|
| 190 |
subtest 'Search patrons' => sub { |
| 191 |
plan tests => 27; |
| 192 |
|
| 193 |
setup(); |
| 186 |
my $total_number_of_patrons = Koha::Patrons->search->count; |
194 |
my $total_number_of_patrons = Koha::Patrons->search->count; |
| 187 |
my $table_id = "memberresultst"; |
195 |
my $table_id = "memberresultst"; |
| 188 |
|
196 |
|
|
Lines 190-203
subtest 'Search patrons' => sub {
Link Here
|
| 190 |
C4::Context->set_preference('DefaultPatronSearchFields',""); |
198 |
C4::Context->set_preference('DefaultPatronSearchFields',""); |
| 191 |
C4::Context->set_preference('DefaultPatronSearchMethod',"contains"); |
199 |
C4::Context->set_preference('DefaultPatronSearchMethod',"contains"); |
| 192 |
my $searchable_attributes = Koha::Patron::Attribute::Types->search({ staff_searchable => 1 })->count(); |
200 |
my $searchable_attributes = Koha::Patron::Attribute::Types->search({ staff_searchable => 1 })->count(); |
| 193 |
my $PatronsPerPage = 15; |
|
|
| 194 |
my $nb_standard_fields = 13 + $searchable_attributes; # Standard fields, plus one searchable attribute |
201 |
my $nb_standard_fields = 13 + $searchable_attributes; # Standard fields, plus one searchable attribute |
| 195 |
C4::Context->set_preference('PatronsPerPage', $PatronsPerPage); |
|
|
| 196 |
$driver->get( $base_url . "/members/members-home.pl" ); |
202 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 197 |
my @adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
203 |
my @adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
| 198 |
is( scalar @adv_options, $nb_standard_fields + 1, 'All standard fields are searchable if DefaultPatronSearchFields not set. middle_name is there.'); |
204 |
is( scalar @adv_options, $nb_standard_fields + 1, 'All standard fields are searchable if DefaultPatronSearchFields not set. middle_name is there.'); |
| 199 |
is( $adv_options[0]->get_value(), 'standard', 'Standard search uses value "standard"'); |
205 |
is( $adv_options[0]->get_value(), 'standard', 'Standard search uses value "standard"'); |
| 200 |
my @filter_options = $driver->find_elements('//select[@id="searchfieldstype_filter"]/option'); |
206 |
my @filter_options = $driver->find_elements('//select[@class="searchfieldstype_filter"]/option'); |
| 201 |
is( scalar @filter_options, $nb_standard_fields + 1, 'All standard fields + middle_name are searchable by filter if DefaultPatronSearchFields not set'); |
207 |
is( scalar @filter_options, $nb_standard_fields + 1, 'All standard fields + middle_name are searchable by filter if DefaultPatronSearchFields not set'); |
| 202 |
is( $filter_options[0]->get_value(), 'standard', 'Standard filter uses hard coded value "standard" DefaultPatronSearchFields not set'); |
208 |
is( $filter_options[0]->get_value(), 'standard', 'Standard filter uses hard coded value "standard" DefaultPatronSearchFields not set'); |
| 203 |
C4::Context->set_preference('DefaultPatronSearchFields',"firstname|initials"); |
209 |
C4::Context->set_preference('DefaultPatronSearchFields',"firstname|initials"); |
|
Lines 205-225
subtest 'Search patrons' => sub {
Link Here
|
| 205 |
@adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
211 |
@adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
| 206 |
is( scalar @adv_options, $nb_standard_fields, 'New option added when DefaultPatronSearchFields is populated with a field. Note that middle_name disappears, we do not want it if not part of DefaultPatronSearchFields'); |
212 |
is( scalar @adv_options, $nb_standard_fields, 'New option added when DefaultPatronSearchFields is populated with a field. Note that middle_name disappears, we do not want it if not part of DefaultPatronSearchFields'); |
| 207 |
is( $adv_options[0]->get_value(), 'standard', 'Standard search uses value "standard"'); |
213 |
is( $adv_options[0]->get_value(), 'standard', 'Standard search uses value "standard"'); |
| 208 |
@filter_options = $driver->find_elements('//select[@id="searchfieldstype_filter"]/option'); |
214 |
@filter_options = $driver->find_elements('//select[@class="searchfieldstype_filter"]/option'); |
| 209 |
is( scalar @filter_options, $nb_standard_fields, 'New filter option added when DefaultPatronSearchFields is populated with a field'); |
215 |
is( scalar @filter_options, $nb_standard_fields, 'New filter option added when DefaultPatronSearchFields is populated with a field'); |
| 210 |
is( $filter_options[0]->get_value(), 'standard', 'Standard filter uses value "standard"'); |
216 |
is( $filter_options[0]->get_value(), 'standard', 'Standard filter uses value "standard"'); |
| 211 |
$driver->get( $base_url . "/members/members-home.pl" ); |
217 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 212 |
@adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
218 |
@adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
| 213 |
@filter_options = $driver->find_elements('//select[@id="searchfieldstype_filter"]/option'); |
219 |
@filter_options = $driver->find_elements('//select[@class="searchfieldstype_filter"]/option'); |
| 214 |
is( scalar @adv_options, $nb_standard_fields, 'Invalid option not added when DefaultPatronSearchFields is populated with an invalid field'); |
220 |
is( scalar @adv_options, $nb_standard_fields, 'Invalid option not added when DefaultPatronSearchFields is populated with an invalid field'); |
| 215 |
is( scalar @filter_options, $nb_standard_fields, 'Invalid filter option not added when DefaultPatronSearchFields is populated with an invalid field'); |
221 |
is( scalar @filter_options, $nb_standard_fields, 'Invalid filter option not added when DefaultPatronSearchFields is populated with an invalid field'); |
| 216 |
|
222 |
|
| 217 |
# NOTE: We should probably ensure the bad field is removed from 'standard' search here, else searches are broken |
223 |
# NOTE: We should probably ensure the bad field is removed from 'standard' search here, else searches are broken |
| 218 |
C4::Context->set_preference('DefaultPatronSearchFields',""); |
224 |
C4::Context->set_preference('DefaultPatronSearchFields',""); |
| 219 |
$driver->get( $base_url . "/members/members-home.pl" ); |
225 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 220 |
$s->fill_form( { search_patron_filter => 'test_patron' } ); |
226 |
$s->fill_form( { 'class=search_patron_filter' => 'test_patron' } ); |
| 221 |
$s->submit_form; |
227 |
$s->submit_form; |
| 222 |
my $first_patron = $patrons[0]; |
228 |
my $first_patron = Koha::Patrons->search( { surname => { like => 'test_patron_%' } } )->next; |
| 223 |
|
229 |
|
| 224 |
sleep $DT_delay && $s->wait_for_ajax; |
230 |
sleep $DT_delay && $s->wait_for_ajax; |
| 225 |
my @td = $driver->find_elements('//table[@id="'.$table_id.'"]/tbody/tr/td'); |
231 |
my @td = $driver->find_elements('//table[@id="'.$table_id.'"]/tbody/tr/td'); |
|
Lines 254-260
subtest 'Search patrons' => sub {
Link Here
|
| 254 |
); |
260 |
); |
| 255 |
|
261 |
|
| 256 |
$driver->get( $base_url . "/members/members-home.pl" ); |
262 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 257 |
$s->fill_form( { search_patron_filter => 'test_patron' } ); |
263 |
$s->fill_form( { 'class=search_patron_filter' => 'test_patron' } ); |
| 258 |
$s->submit_form; |
264 |
$s->submit_form; |
| 259 |
sleep $DT_delay && $s->wait_for_ajax; |
265 |
sleep $DT_delay && $s->wait_for_ajax; |
| 260 |
|
266 |
|
|
Lines 262-273
subtest 'Search patrons' => sub {
Link Here
|
| 262 |
sleep $DT_delay && $s->wait_for_ajax; |
268 |
sleep $DT_delay && $s->wait_for_ajax; |
| 263 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries (filtered from %s total entries)', $PatronsPerPage, 26, $total_number_of_patrons), 'Searching in standard brings back correct results' ); |
269 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries (filtered from %s total entries)', $PatronsPerPage, 26, $total_number_of_patrons), 'Searching in standard brings back correct results' ); |
| 264 |
|
270 |
|
| 265 |
$s->driver->find_element('//table[@id="'.$table_id.'"]//th[@data-filter="libraries"]/select/option[@value="'.$library->branchcode.'"]')->click; |
271 |
$s->driver->find_element('//table[@id="'.$table_id.'"]//th[@data-filter="libraries"]/select/option[@value="'.$first_patron->library->branchcode.'"]')->click; |
| 266 |
sleep $DT_delay && $s->wait_for_ajax; |
272 |
sleep $DT_delay && $s->wait_for_ajax; |
| 267 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries (filtered from %s total entries)', $PatronsPerPage, 25, $total_number_of_patrons), 'Filtering on library works in combination with main search' ); |
273 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries (filtered from %s total entries)', $PatronsPerPage, 25, $total_number_of_patrons), 'Filtering on library works in combination with main search' ); |
| 268 |
|
274 |
|
| 269 |
# Reset the filters |
275 |
# Reset the filters |
| 270 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="clear_search"]')->click(); |
276 |
$driver->find_element('//form[@class="patron_search_form"]//*[@class="btn btn-default clear_search"]')->click(); |
| 271 |
$s->submit_form; |
277 |
$s->submit_form; |
| 272 |
sleep $DT_delay && $s->wait_for_ajax; |
278 |
sleep $DT_delay && $s->wait_for_ajax; |
| 273 |
|
279 |
|
|
Lines 275-312
subtest 'Search patrons' => sub {
Link Here
|
| 275 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries', $PatronsPerPage, $total_number_of_patrons), 'Resetting filters works as expected' ); |
281 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries', $PatronsPerPage, $total_number_of_patrons), 'Resetting filters works as expected' ); |
| 276 |
|
282 |
|
| 277 |
# Pattern terms must be split |
283 |
# Pattern terms must be split |
| 278 |
$s->fill_form( { search_patron_filter => 'test patron' } ); |
284 |
$s->fill_form( { 'class=search_patron_filter' => 'test patron' } ); |
| 279 |
$s->submit_form; |
285 |
$s->submit_form; |
| 280 |
|
286 |
|
| 281 |
sleep $DT_delay && $s->wait_for_ajax; |
287 |
sleep $DT_delay && $s->wait_for_ajax; |
| 282 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries (filtered from %s total entries)', $PatronsPerPage, 26, $total_number_of_patrons) ); |
288 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries (filtered from %s total entries)', $PatronsPerPage, 26, $total_number_of_patrons) ); |
| 283 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="clear_search"]')->click(); |
289 |
$driver->find_element('//form[@class="patron_search_form"]//*[@class="btn btn-default clear_search"]')->click(); |
| 284 |
$s->submit_form; |
290 |
$s->submit_form; |
| 285 |
sleep $DT_delay && $s->wait_for_ajax; |
291 |
sleep $DT_delay && $s->wait_for_ajax; |
| 286 |
|
292 |
|
| 287 |
# Search on non-searchable attribute, we expect no result! |
293 |
# Search on non-searchable attribute, we expect no result! |
| 288 |
$s->fill_form( { search_patron_filter => 'test_attr_1' } ); |
294 |
$s->fill_form( { 'class=search_patron_filter' => 'test_attr_1' } ); |
| 289 |
$s->submit_form; |
295 |
$s->submit_form; |
| 290 |
sleep $DT_delay && $s->wait_for_ajax; |
296 |
sleep $DT_delay && $s->wait_for_ajax; |
| 291 |
|
297 |
|
| 292 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('No entries to show (filtered from %s total entries)', $total_number_of_patrons), 'Searching on a non-searchable attribute returns no results' ); |
298 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('No entries to show (filtered from %s total entries)', $total_number_of_patrons), 'Searching on a non-searchable attribute returns no results' ); |
| 293 |
|
299 |
|
| 294 |
# clear form |
300 |
# clear form |
| 295 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="clear_search"]')->click(); |
301 |
$driver->find_element('//form[@class="patron_search_form"]//*[@class="btn btn-default clear_search"]')->click(); |
| 296 |
|
302 |
|
| 297 |
# Search on searchable attribute, we expect 2 patrons |
303 |
# Search on searchable attribute, we expect 2 patrons |
| 298 |
$s->fill_form( { search_patron_filter => 'test_attr_2' } ); |
304 |
$s->fill_form( { 'class=search_patron_filter' => 'test_attr_2' } ); |
| 299 |
$s->submit_form; |
305 |
$s->submit_form; |
| 300 |
sleep $DT_delay && $s->wait_for_ajax; |
306 |
sleep $DT_delay && $s->wait_for_ajax; |
| 301 |
|
307 |
|
| 302 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries (filtered from %s total entries)', 2, 2, $total_number_of_patrons), 'Searching on a searchable attribute returns correct results' ); |
308 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries (filtered from %s total entries)', 2, 2, $total_number_of_patrons), 'Searching on a searchable attribute returns correct results' ); |
| 303 |
|
309 |
|
| 304 |
# clear form |
310 |
# clear form |
| 305 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="clear_search"]')->click(); |
311 |
$driver->find_element('//form[@class="patron_search_form"]//*[@class="btn btn-default clear_search"]')->click(); |
| 306 |
|
312 |
|
| 307 |
# Search on searchable attribute as specific field, we expect 2 patrons |
313 |
# Search on searchable attribute as specific field, we expect 2 patrons |
| 308 |
$s->fill_form( { search_patron_filter => 'test_attr_3' } ); |
314 |
$s->fill_form( { 'class=search_patron_filter' => 'test_attr_3' } ); |
| 309 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="searchfieldstype_filter"]//option[@value="_ATTR_'.$attribute_type_searchable_not_default->code.'"]')->click(); |
315 |
$driver->find_element('//form[@class="patron_search_form"]//*[@class="searchfieldstype_filter"]//option[@value="_ATTR_'.$attribute_type_searchable_not_default->code.'"]')->click(); |
| 310 |
$s->submit_form; |
316 |
$s->submit_form; |
| 311 |
sleep $DT_delay && $s->wait_for_ajax; |
317 |
sleep $DT_delay && $s->wait_for_ajax; |
| 312 |
|
318 |
|
|
Lines 320-326
subtest 'Search patrons' => sub {
Link Here
|
| 320 |
|
326 |
|
| 321 |
# Adding the surname of the first patron in the "Name" column |
327 |
# Adding the surname of the first patron in the "Name" column |
| 322 |
# We expect only 1 result |
328 |
# We expect only 1 result |
| 323 |
$s->driver->find_element('//table[@id="'.$table_id.'"]//input[@placeholder="Name search"]')->send_keys($patrons[0]->surname); |
329 |
$s->driver->find_element('//table[@id="'.$table_id.'"]//input[@placeholder="Name search"]')->send_keys($first_patron->surname); |
| 324 |
sleep $DT_delay && $s->wait_for_ajax; |
330 |
sleep $DT_delay && $s->wait_for_ajax; |
| 325 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries (filtered from %s total entries)', 1, 1, $total_number_of_patrons), 'Refining with header filters works to further filter the original query' ); |
331 |
is( $driver->find_element('//div[@id="'.$table_id.'_info"]')->get_text, sprintf('Showing 1 to %s of %s entries (filtered from %s total entries)', 1, 1, $total_number_of_patrons), 'Refining with header filters works to further filter the original query' ); |
| 326 |
|
332 |
|
|
Lines 330-336
subtest 'Search patrons' => sub {
Link Here
|
| 330 |
|
336 |
|
| 331 |
C4::Context->set_preference( 'PatronsPerPage', 5 ); |
337 |
C4::Context->set_preference( 'PatronsPerPage', 5 ); |
| 332 |
$driver->get( $base_url . "/members/members-home.pl" ); |
338 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 333 |
$s->fill_form( { search_patron_filter => 'test_patron' } ); |
339 |
$s->fill_form( { 'class=search_patron_filter' => 'test_patron' } ); |
| 334 |
$s->submit_form; |
340 |
$s->submit_form; |
| 335 |
sleep $DT_delay && $s->wait_for_ajax; |
341 |
sleep $DT_delay && $s->wait_for_ajax; |
| 336 |
my $patron_selected_text = $driver->find_element('//div[@id="table_search_selections"]/span')->get_text; |
342 |
my $patron_selected_text = $driver->find_element('//div[@id="table_search_selections"]/span')->get_text; |
|
Lines 356-362
subtest 'Search patrons' => sub {
Link Here
|
| 356 |
|
362 |
|
| 357 |
# Perform another search |
363 |
# Perform another search |
| 358 |
$driver->get( $base_url . "/members/members-home.pl" ); |
364 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 359 |
$s->fill_form( { search_patron_filter => 'test_patron' } ); |
365 |
$s->fill_form( { 'class=search_patron_filter' => 'test_patron' } ); |
| 360 |
$s->submit_form; |
366 |
$s->submit_form; |
| 361 |
sleep $DT_delay && $s->wait_for_ajax; |
367 |
sleep $DT_delay && $s->wait_for_ajax; |
| 362 |
$patron_selected_text = $driver->find_element('//div[@id="table_search_selections"]/span')->get_text; |
368 |
$patron_selected_text = $driver->find_element('//div[@id="table_search_selections"]/span')->get_text; |
|
Lines 383-389
subtest 'Search patrons' => sub {
Link Here
|
| 383 |
# We have a patron with date of birth=1980-06-17 => formatted as 17/06/1980 |
389 |
# We have a patron with date of birth=1980-06-17 => formatted as 17/06/1980 |
| 384 |
|
390 |
|
| 385 |
$driver->get( $base_url . "/members/members-home.pl" ); |
391 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 386 |
$s->fill_form( { search_patron_filter => 'test_patron' } ); |
392 |
$s->fill_form( { 'class=search_patron_filter' => 'test_patron' } ); |
| 387 |
$s->submit_form; |
393 |
$s->submit_form; |
| 388 |
sleep $DT_delay && $s->wait_for_ajax; |
394 |
sleep $DT_delay && $s->wait_for_ajax; |
| 389 |
|
395 |
|
|
Lines 393-398
subtest 'Search patrons' => sub {
Link Here
|
| 393 |
|
399 |
|
| 394 |
$dob_search_filter->send_keys('1980'); |
400 |
$dob_search_filter->send_keys('1980'); |
| 395 |
sleep $DT_delay && $s->wait_for_ajax; |
401 |
sleep $DT_delay && $s->wait_for_ajax; |
|
|
402 |
my $patron_27 = Koha::Patrons->search( { surname => 'test_patron_27' } )->next; |
| 396 |
is( is_patron_shown($patron_27), 1, 'search by correct year shows the patron' ); |
403 |
is( is_patron_shown($patron_27), 1, 'search by correct year shows the patron' ); |
| 397 |
$dob_search_filter->clear; |
404 |
$dob_search_filter->clear; |
| 398 |
|
405 |
|
|
Lines 427-433
subtest 'Search patrons' => sub {
Link Here
|
| 427 |
$dob_search_filter->clear; |
434 |
$dob_search_filter->clear; |
| 428 |
}; |
435 |
}; |
| 429 |
|
436 |
|
| 430 |
$driver->quit(); |
437 |
teardown(); |
|
|
438 |
|
| 439 |
}; |
| 440 |
|
| 441 |
subtest 'Search patrons in modal' => sub { |
| 442 |
plan tests => 2; |
| 443 |
|
| 444 |
setup(); |
| 445 |
|
| 446 |
my $total_number_of_patrons = Koha::Patrons->search->count; |
| 447 |
|
| 448 |
$driver->set_window_size( 3840, 10800 ); |
| 449 |
|
| 450 |
subtest 'Add guarantor - simple' => sub { |
| 451 |
plan tests => 4; |
| 452 |
|
| 453 |
my $table_id = "memberresultst"; |
| 454 |
|
| 455 |
my $mainpage = $s->base_url . q|mainpage.pl|; |
| 456 |
$driver->get($mainpage . q|?logout.x=1|); |
| 457 |
$s->auth; |
| 458 |
|
| 459 |
# Go to the add patron form |
| 460 |
$driver->get( $base_url . "/members/memberentry.pl" ); |
| 461 |
|
| 462 |
# Click "Add guarantor" |
| 463 |
$driver->find_element('//a[@href="#patron_search_modal"]')->click(); |
| 464 |
|
| 465 |
# Wait for the modal to be visible |
| 466 |
$s->wait_for_element_visible('//div[@id="patron_search_modal"]//div[@class="modal-header"]'); |
| 467 |
|
| 468 |
# Search for our test patrons |
| 469 |
$s->fill_form( { 'class=search_patron_filter' => 'test_patron' } ); |
| 470 |
$s->submit_form; |
| 471 |
sleep $DT_delay && $s->wait_for_ajax; |
| 472 |
|
| 473 |
# => the table is correctly displayed |
| 474 |
is( |
| 475 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->get_text, |
| 476 |
sprintf( |
| 477 |
'Showing 1 to %s of %s entries (filtered from %s total entries)', $PatronsPerPage, 26, |
| 478 |
$total_number_of_patrons |
| 479 |
), |
| 480 |
'Searching in standard brings back correct results' |
| 481 |
); |
| 482 |
|
| 483 |
# Search for patron 2 and display the patron preview modal |
| 484 |
my $patron = Koha::Patrons->search( { surname => 'test_patron_2' } )->next; |
| 485 |
$driver->find_element( |
| 486 |
sprintf '//a[@data-borrowernumber="%s"][@class="patron_name patron_preview"]', |
| 487 |
$patron->borrowernumber |
| 488 |
)->click; |
| 489 |
$s->wait_for_element_visible('//div[@id="patron_preview_modal"]'); |
| 490 |
sleep $DT_delay && $s->wait_for_ajax; |
| 491 |
|
| 492 |
# => The modal has patron's detail in it |
| 493 |
is( |
| 494 |
$driver->find_element('//div[@id="patron_preview_modal"]//h1')->get_text(), |
| 495 |
sprintf( |
| 496 |
"%s %s %s (%s) %s (%s)", $patron->title, $patron->firstname, $patron->middle_name, $patron->othernames, |
| 497 |
$patron->surname, $patron->cardnumber |
| 498 |
) |
| 499 |
); |
| 500 |
|
| 501 |
# Close the patron preview modal |
| 502 |
$driver->find_element('//div[@id="patron_preview_modal"]//input[@class="close"]')->click; |
| 503 |
$s->wait_for_element_hidden('//div[@id="patron_preview_modal"]'); |
| 504 |
|
| 505 |
# Select patron 2 |
| 506 |
$driver->find_element( |
| 507 |
sprintf '//a[@data-borrowernumber="%s"][@class="btn btn-default btn-xs select_user"]', |
| 508 |
$patron->borrowernumber |
| 509 |
)->click; |
| 510 |
|
| 511 |
# Wait for the modal to be hidden |
| 512 |
$s->wait_for_element_hidden('//div[@id="patron_search_modal"]//div[@class="modal-header"]'); |
| 513 |
|
| 514 |
# => The guarantor block has the info of the selected patron |
| 515 |
is( |
| 516 |
$driver->find_element('//a[@class="new_guarantor_link"]')->get_text(), |
| 517 |
sprintf( "%s %s (%s)", $patron->firstname, $patron->surname, $patron->cardnumber ) |
| 518 |
); |
| 519 |
is( |
| 520 |
$driver->find_element('//input[@class="new_guarantor_id noEnterSubmit"]')->get_value(), |
| 521 |
$patron->borrowernumber |
| 522 |
); |
| 523 |
|
| 524 |
}; |
| 525 |
|
| 526 |
subtest 'Add funds - double' => sub { |
| 527 |
plan tests => 11; |
| 528 |
|
| 529 |
my $table_id = "patron_search_modal_owner_table"; |
| 530 |
|
| 531 |
my $mainpage = $s->base_url . q|mainpage.pl|; |
| 532 |
$driver->get($mainpage . q|?logout.x=1|); |
| 533 |
$s->auth; |
| 534 |
|
| 535 |
# Go to the add patron form |
| 536 |
$driver->get( $base_url . "/admin/aqbudgets.pl?op=add_form&budget_id=1&budget_period_id=1" ); |
| 537 |
|
| 538 |
# Click "Select owner" |
| 539 |
$driver->find_element('//a[@href="#patron_search_modal_owner"]')->click(); |
| 540 |
|
| 541 |
# Add { acquisition => budget_modify } subpermission to some patrons |
| 542 |
my $dbh = C4::Context->dbh; |
| 543 |
my $patrons = Koha::Patrons->search( { surname => { like => 'test_patron_2%' } } ); |
| 544 |
while ( my $patron = $patrons->next ) { |
| 545 |
$dbh->do( |
| 546 |
q{INSERT INTO user_permissions (borrowernumber, module_bit, code) VALUES (?, ?, ?)}, {}, |
| 547 |
$patron->borrowernumber, 11, "budget_modify" |
| 548 |
); |
| 549 |
} |
| 550 |
|
| 551 |
# Wait for the modal to be visible |
| 552 |
$s->wait_for_element_visible('//div[@id="patron_search_modal_owner"]//div[@class="modal-header"]'); |
| 553 |
|
| 554 |
# Search for our test patrons |
| 555 |
$driver->find_element('//div[@id="patron_search_modal_owner"]//input[@class="search_patron_filter"]') |
| 556 |
->send_keys('test_patron'); |
| 557 |
$driver->find_element('//div[@id="patron_search_modal_owner"]//input[@type="submit"]')->click; |
| 558 |
|
| 559 |
sleep $DT_delay && $s->wait_for_ajax; |
| 560 |
|
| 561 |
# => the table is correctly displayed |
| 562 |
is( |
| 563 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->is_displayed, |
| 564 |
1, |
| 565 |
); |
| 566 |
|
| 567 |
# Search for patron 2 and display the patron preview modal |
| 568 |
my $patron = Koha::Patrons->search( { surname => 'test_patron_2' } )->next; |
| 569 |
$driver->find_element( |
| 570 |
sprintf '//a[@data-borrowernumber="%s"][@class="patron_name patron_preview"]', |
| 571 |
$patron->borrowernumber |
| 572 |
)->click; |
| 573 |
$s->wait_for_element_visible('//div[@id="patron_preview_modal"]'); |
| 574 |
sleep $DT_delay && $s->wait_for_ajax; |
| 575 |
|
| 576 |
# => The modal has patron's detail in it |
| 577 |
is( |
| 578 |
$driver->find_element('//div[@id="patron_preview_modal"]//h1')->get_text(), |
| 579 |
sprintf( |
| 580 |
"%s %s %s (%s) %s (%s)", $patron->title, $patron->firstname, $patron->middle_name, $patron->othernames, |
| 581 |
$patron->surname, $patron->cardnumber |
| 582 |
) |
| 583 |
); |
| 584 |
|
| 585 |
# Close the patron preview modal |
| 586 |
$driver->find_element('//div[@id="patron_preview_modal"]//input[@class="close"]')->click; |
| 587 |
$s->wait_for_element_hidden('//div[@id="patron_preview_modal"]'); |
| 588 |
|
| 589 |
# Select patron 2 |
| 590 |
$driver->find_element( |
| 591 |
sprintf '//a[@data-borrowernumber="%s"][@class="btn btn-default btn-xs select_user"]', |
| 592 |
$patron->borrowernumber |
| 593 |
)->click; |
| 594 |
|
| 595 |
# Wait for the modal to be hidden |
| 596 |
$s->wait_for_element_hidden('//div[@id="patron_search_modal"]//div[@class="modal-header"]'); |
| 597 |
|
| 598 |
# => The block has the info of the selected patron |
| 599 |
is( |
| 600 |
$driver->find_element('//span[@id="budget_owner_name"]')->get_text(), |
| 601 |
sprintf( "%s %s", $patron->firstname, $patron->surname ) |
| 602 |
); |
| 603 |
is( |
| 604 |
$driver->find_element('//input[@id="budget_owner_id"]')->get_value(), |
| 605 |
$patron->borrowernumber |
| 606 |
); |
| 607 |
|
| 608 |
$table_id = "patron_search_modal_users_table"; |
| 609 |
|
| 610 |
# Click "Add users" |
| 611 |
$driver->find_element('//a[@href="#patron_search_modal_users"]')->click(); |
| 612 |
|
| 613 |
# Wait for the modal to be visible |
| 614 |
$s->wait_for_element_visible('//div[@id="patron_search_modal_users"]//div[@class="modal-header"]'); |
| 615 |
|
| 616 |
# Search for our test patrons |
| 617 |
$driver->find_element('//div[@id="patron_search_modal_users"]//input[@class="search_patron_filter"]') |
| 618 |
->send_keys('test_patron'); |
| 619 |
$driver->find_element('//div[@id="patron_search_modal_users"]//input[@type="submit"]')->click; |
| 620 |
|
| 621 |
sleep $DT_delay && $s->wait_for_ajax; |
| 622 |
|
| 623 |
# => the table is correctly displayed |
| 624 |
is( |
| 625 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->is_displayed, |
| 626 |
1, |
| 627 |
); |
| 628 |
|
| 629 |
# Search for patron 2 and display the patron preview modal |
| 630 |
$patron = Koha::Patrons->search( { surname => 'test_patron_2' } )->next; |
| 631 |
$driver->find_element( |
| 632 |
sprintf '//a[@data-borrowernumber="%s"][@class="patron_name patron_preview"]', |
| 633 |
$patron->borrowernumber |
| 634 |
)->click; |
| 635 |
$s->wait_for_element_visible('//div[@id="patron_preview_modal"]'); |
| 636 |
sleep $DT_delay && $s->wait_for_ajax; |
| 637 |
|
| 638 |
# => The modal has patron's detail in it |
| 639 |
is( |
| 640 |
$driver->find_element('//div[@id="patron_preview_modal"]//h1')->get_text(), |
| 641 |
sprintf( |
| 642 |
"%s %s %s (%s) %s (%s)", $patron->title, $patron->firstname, $patron->middle_name, $patron->othernames, |
| 643 |
$patron->surname, $patron->cardnumber |
| 644 |
) |
| 645 |
); |
| 646 |
|
| 647 |
# Close the patron preview modal |
| 648 |
$driver->find_element('//div[@id="patron_preview_modal"]//input[@class="close"]')->click; |
| 649 |
$s->wait_for_element_hidden('//div[@id="patron_preview_modal"]'); |
| 650 |
|
| 651 |
# Select patron 2 |
| 652 |
$driver->find_element( |
| 653 |
sprintf '//a[@data-borrowernumber="%s"][@class="btn btn-default btn-xs add_user"]', |
| 654 |
$patron->borrowernumber |
| 655 |
)->click; |
| 656 |
|
| 657 |
# The modal is still displayed |
| 658 |
is( |
| 659 |
$driver->find_element('//div[@id="patron_search_modal_users"]//div[@class="modal-header"]')->is_displayed, |
| 660 |
1, |
| 661 |
); |
| 662 |
|
| 663 |
# Info has been added about the patron |
| 664 |
is( |
| 665 |
$driver->find_element('//div[@id="patron_search_modal_users"]//div[@class="info"]')->get_text, |
| 666 |
sprintf( "Patron '%s %s' added.", $patron->firstname, $patron->surname ) |
| 667 |
); |
| 668 |
|
| 669 |
# Select patron 2 again |
| 670 |
$driver->find_element( |
| 671 |
sprintf '//a[@data-borrowernumber="%s"][@class="btn btn-default btn-xs add_user"]', |
| 672 |
$patron->borrowernumber |
| 673 |
)->click; |
| 674 |
|
| 675 |
# Warning has been added about the patron |
| 676 |
is( |
| 677 |
$driver->find_element('//div[@id="patron_search_modal_users"]//div[@class="error"]')->get_text, |
| 678 |
sprintf( "Patron '%s %s' is already in the list.", $patron->firstname, $patron->surname ) |
| 679 |
); |
| 680 |
|
| 681 |
# Click "Close" |
| 682 |
$driver->find_element('//div[@id="patron_search_modal_users"]//div[@class="modal-footer"]//a')->click, |
| 683 |
|
| 684 |
# The modal is closed |
| 685 |
if ( |
| 686 |
$driver->find_element('//div[@id="patron_search_modal_users"]//div[@class="modal-header"]')->is_displayed, |
| 687 |
0, |
| 688 |
); |
| 689 |
|
| 690 |
# => The block has the info of the selected patron |
| 691 |
is( |
| 692 |
$driver->find_element( sprintf '//*[@id="budget_users"]/*[@id="user_%s"]/a', $patron->borrowernumber ) |
| 693 |
->get_text(), |
| 694 |
sprintf( "%s %s", $patron->firstname, $patron->surname ) |
| 695 |
); |
| 696 |
is( |
| 697 |
$driver->find_element('//input[@id="budget_users_id"]')->get_value(), |
| 698 |
sprintf( ":%s", $patron->borrowernumber ), # FIXME There is an extra ':' here |
| 699 |
); |
| 700 |
}; |
| 701 |
|
| 702 |
teardown(); |
| 703 |
|
| 431 |
}; |
704 |
}; |
| 432 |
|
705 |
|
| 433 |
sub is_patron_shown { |
706 |
sub is_patron_shown { |