|
Lines 17-27
Link Here
|
| 17 |
|
17 |
|
| 18 |
use Modern::Perl; |
18 |
use Modern::Perl; |
| 19 |
|
19 |
|
|
|
20 |
my $original_dateformat = C4::Context->preference('dateformat'); |
| 21 |
my $original_DefaultPatronSearchFields = C4::Context->preference('DefaultPatronSearchFields'); |
| 22 |
my $original_DefaultPatronSearchMethod = C4::Context->preference('DefaultPatronSearchMethod'); |
| 23 |
my $original_PatronsPerPage = C4::Context->preference('PatronsPerPage'); |
| 20 |
our @cleanup; |
24 |
our @cleanup; |
|
|
25 |
|
| 21 |
END { |
26 |
END { |
| 22 |
unless ( @cleanup ) { say "WARNING: Cleanup failed!" } |
27 |
|
|
|
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 ); |
| 23 |
$_->delete for @cleanup; |
33 |
$_->delete for @cleanup; |
| 24 |
}; |
34 |
} |
| 25 |
|
35 |
|
| 26 |
use C4::Context; |
36 |
use C4::Context; |
| 27 |
|
37 |
|
|
Lines 37-49
use t::lib::Selenium;
Link Here
|
| 37 |
use t::lib::TestBuilder; |
47 |
use t::lib::TestBuilder; |
| 38 |
|
48 |
|
| 39 |
eval { require Selenium::Remote::Driver; }; |
49 |
eval { require Selenium::Remote::Driver; }; |
| 40 |
if ( $@ ) { |
50 |
if ($@) { |
| 41 |
plan skip_all => "Selenium::Remote::Driver is needed for selenium tests."; |
51 |
plan skip_all => "Selenium::Remote::Driver is needed for selenium tests."; |
| 42 |
} else { |
52 |
} else { |
| 43 |
plan tests => 1; |
53 |
plan tests => 1; |
| 44 |
} |
54 |
} |
| 45 |
|
55 |
|
| 46 |
|
|
|
| 47 |
my $s = t::lib::Selenium->new; |
56 |
my $s = t::lib::Selenium->new; |
| 48 |
my $driver = $s->driver; |
57 |
my $driver = $s->driver; |
| 49 |
my $opac_base_url = $s->opac_base_url; |
58 |
my $opac_base_url = $s->opac_base_url; |
|
Lines 52-84
my $builder = t::lib::TestBuilder->new;
Link Here
|
| 52 |
my $schema = Koha::Database->schema; |
61 |
my $schema = Koha::Database->schema; |
| 53 |
|
62 |
|
| 54 |
subtest 'Search patrons' => sub { |
63 |
subtest 'Search patrons' => sub { |
| 55 |
plan tests => 25; |
64 |
plan tests => 26; |
| 56 |
|
65 |
|
| 57 |
if ( Koha::Patrons->search({surname => {-like => "test_patron_%"}})->count ) { |
66 |
if ( Koha::Patrons->search( { surname => { -like => "test_patron_%" } } )->count ) { |
| 58 |
BAIL_OUT("Cannot run this test, data we need to create already exist in the DB"); |
67 |
BAIL_OUT("Cannot run this test, data we need to create already exist in the DB"); |
| 59 |
} |
68 |
} |
| 60 |
my @patrons; |
69 |
my @patrons; |
| 61 |
my $borrowernotes = q|<strong>just 'a" note</strong> \123 ❤|; |
70 |
my $borrowernotes = q|<strong>just 'a" note</strong> \123 ❤|; |
| 62 |
my $borrowernotes_displayed = q|just 'a" note \123 ❤|; |
71 |
my $borrowernotes_displayed = q|just 'a" note \123 ❤|; |
| 63 |
my $branchname = q|<strong>just 'another" library</strong> \123 ❤|; |
72 |
my $branchname = q|<strong>just 'another" library</strong> \123 ❤|; |
| 64 |
my $firstname = q|<strong>fir's"tname</strong> \123 ❤|; |
73 |
my $firstname = q|<strong>fir's"tname</strong> \123 ❤|; |
| 65 |
my $address = q|<strong>add'res"s</strong> \123 ❤|; |
74 |
my $address = q|<strong>add'res"s</strong> \123 ❤|; |
| 66 |
my $email = q|a<strong>bad_email</strong>@example\123 ❤.com|; |
75 |
my $email = q|a<strong>bad_email</strong>@example\123 ❤.com|; |
| 67 |
my $patron_category = $builder->build_object( |
76 |
my $patron_category = $builder->build_object( |
| 68 |
{ |
77 |
{ |
| 69 |
class => 'Koha::Patron::Categories', |
78 |
class => 'Koha::Patron::Categories', |
| 70 |
value => { category_type => 'A' } |
79 |
value => { category_type => 'A' } |
| 71 |
} |
80 |
} |
| 72 |
); |
81 |
); |
| 73 |
my $library = $builder->build_object( |
82 |
my $library = $builder->build_object( { class => 'Koha::Libraries', value => { branchname => $branchname } } ); |
| 74 |
{ class => 'Koha::Libraries', value => { branchname => $branchname } } |
|
|
| 75 |
); |
| 76 |
my $default_patron_search_fields = C4::Context->preference('DefaultPatronSearchFields'); |
| 77 |
my $default_patron_search_method = C4::Context->preference('DefaultPatronSearchMethod'); |
| 78 |
my $default_patron_per_page = C4::Context->preference('PatronsPerPage'); |
| 79 |
for my $i ( 1 .. 25 ) { |
83 |
for my $i ( 1 .. 25 ) { |
| 80 |
push @patrons, |
84 |
push @patrons, |
| 81 |
$builder->build_object( |
85 |
$builder->build_object( |
| 82 |
{ |
86 |
{ |
| 83 |
class => 'Koha::Patrons', |
87 |
class => 'Koha::Patrons', |
| 84 |
value => { |
88 |
value => { |
|
Lines 91-105
subtest 'Search patrons' => sub {
Link Here
|
| 91 |
email => $email, |
95 |
email => $email, |
| 92 |
} |
96 |
} |
| 93 |
} |
97 |
} |
| 94 |
); |
98 |
); |
| 95 |
} |
99 |
} |
| 96 |
|
100 |
|
| 97 |
push @patrons, $builder->build_object( |
101 |
push @patrons, $builder->build_object( |
| 98 |
{ |
102 |
{ |
| 99 |
class => 'Koha::Patrons', |
103 |
class => 'Koha::Patrons', |
| 100 |
value => { |
104 |
value => { |
| 101 |
surname => "test", |
105 |
surname => "test", |
| 102 |
firstname => "not_p_a_t_r_o_n", # won't match 'patron' |
106 |
firstname => "not_p_a_t_r_o_n", # won't match 'patron' |
| 103 |
categorycode => $patron_category->categorycode, |
107 |
categorycode => $patron_category->categorycode, |
| 104 |
branchcode => $library->branchcode, |
108 |
branchcode => $library->branchcode, |
| 105 |
borrowernotes => $borrowernotes, |
109 |
borrowernotes => $borrowernotes, |
|
Lines 109-119
subtest 'Search patrons' => sub {
Link Here
|
| 109 |
} |
113 |
} |
| 110 |
); |
114 |
); |
| 111 |
|
115 |
|
| 112 |
my $library_2 = $builder->build_object( |
116 |
my $library_2 = |
| 113 |
{ class => 'Koha::Libraries', value => { branchname => 'X' . $branchname } } |
117 |
$builder->build_object( { class => 'Koha::Libraries', value => { branchname => 'X' . $branchname } } ); |
| 114 |
); |
118 |
my $patron_26 = $builder->build_object( |
| 115 |
push @patrons, |
|
|
| 116 |
$builder->build_object( |
| 117 |
{ |
119 |
{ |
| 118 |
class => 'Koha::Patrons', |
120 |
class => 'Koha::Patrons', |
| 119 |
value => { |
121 |
value => { |
|
Lines 124-132
subtest 'Search patrons' => sub {
Link Here
|
| 124 |
borrowernotes => $borrowernotes, |
126 |
borrowernotes => $borrowernotes, |
| 125 |
address => $address, |
127 |
address => $address, |
| 126 |
email => $email, |
128 |
email => $email, |
|
|
129 |
dateofbirth => '1980-06-17', |
| 127 |
} |
130 |
} |
| 128 |
} |
131 |
} |
| 129 |
); |
132 |
); |
|
|
133 |
push @patrons, $patron_26; |
| 130 |
|
134 |
|
| 131 |
my $attribute_type = Koha::Patron::Attribute::Type->new( |
135 |
my $attribute_type = Koha::Patron::Attribute::Type->new( |
| 132 |
{ |
136 |
{ |
|
Lines 142-220
subtest 'Search patrons' => sub {
Link Here
|
| 142 |
staff_searchable => 1 |
146 |
staff_searchable => 1 |
| 143 |
} |
147 |
} |
| 144 |
)->store; |
148 |
)->store; |
| 145 |
$patrons[0]->extended_attributes([ |
149 |
$patrons[0]->extended_attributes( |
| 146 |
{ code => $attribute_type->code, attribute => 'test_attr_1' }, |
150 |
[ |
| 147 |
{ code => $attribute_type_searchable->code, attribute => 'test_attr_2'}, |
151 |
{ code => $attribute_type->code, attribute => 'test_attr_1' }, |
| 148 |
]); |
152 |
{ code => $attribute_type_searchable->code, attribute => 'test_attr_2' }, |
| 149 |
$patrons[1]->extended_attributes([ |
153 |
] |
| 150 |
{ code => $attribute_type->code, attribute => 'test_attr_1' }, |
154 |
); |
| 151 |
{ code => $attribute_type_searchable->code, attribute => 'test_attr_2'}, |
155 |
$patrons[1]->extended_attributes( |
| 152 |
]); |
156 |
[ |
|
|
157 |
{ code => $attribute_type->code, attribute => 'test_attr_1' }, |
| 158 |
{ code => $attribute_type_searchable->code, attribute => 'test_attr_2' }, |
| 159 |
] |
| 160 |
); |
| 153 |
|
161 |
|
| 154 |
my $total_number_of_patrons = Koha::Patrons->search->count; |
162 |
my $total_number_of_patrons = Koha::Patrons->search->count; |
| 155 |
my $table_id = "memberresultst"; |
163 |
my $table_id = "memberresultst"; |
| 156 |
|
164 |
|
| 157 |
$s->auth; |
165 |
$s->auth; |
| 158 |
C4::Context->set_preference('DefaultPatronSearchFields',""); |
166 |
C4::Context->set_preference( 'DefaultPatronSearchFields', "" ); |
| 159 |
C4::Context->set_preference('DefaultPatronSearchMethod',"contains"); |
167 |
C4::Context->set_preference( 'DefaultPatronSearchMethod', "contains" ); |
| 160 |
my $PatronsPerPage = 15; |
168 |
my $PatronsPerPage = 15; |
| 161 |
my $nb_standard_fields = 13; |
169 |
my $nb_standard_fields = 13; |
| 162 |
C4::Context->set_preference('PatronsPerPage', $PatronsPerPage); |
170 |
C4::Context->set_preference( 'PatronsPerPage', $PatronsPerPage ); |
| 163 |
$driver->get( $base_url . "/members/members-home.pl" ); |
171 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 164 |
my @adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
172 |
my @adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
| 165 |
is( scalar @adv_options, $nb_standard_fields + 1, 'All standard fields are searchable if DefaultPatronSearchFields not set. middle_name is there.'); |
173 |
is( |
| 166 |
is( $adv_options[0]->get_value(), 'firstname,middle_name,surname,othernames,cardnumber,userid', 'Standard search uses hard coded list when DefaultPatronSearchFields not set'); |
174 |
scalar @adv_options, $nb_standard_fields + 1, |
|
|
175 |
'All standard fields are searchable if DefaultPatronSearchFields not set. middle_name is there.' |
| 176 |
); |
| 177 |
is( |
| 178 |
$adv_options[0]->get_value(), 'firstname,middle_name,surname,othernames,cardnumber,userid', |
| 179 |
'Standard search uses hard coded list when DefaultPatronSearchFields not set' |
| 180 |
); |
| 167 |
my @filter_options = $driver->find_elements('//select[@id="searchfieldstype_filter"]/option'); |
181 |
my @filter_options = $driver->find_elements('//select[@id="searchfieldstype_filter"]/option'); |
| 168 |
is( scalar @filter_options, $nb_standard_fields + 1, 'All standard fields + middle_name are searchable by filter if DefaultPatronSearchFields not set'); |
182 |
is( |
| 169 |
is( $filter_options[0]->get_value(), 'firstname,middle_name,surname,othernames,cardnumber,userid', 'Standard filter uses hard coded list when DefaultPatronSearchFields not set'); |
183 |
scalar @filter_options, $nb_standard_fields + 1, |
| 170 |
C4::Context->set_preference('DefaultPatronSearchFields',"firstname,initials"); |
184 |
'All standard fields + middle_name are searchable by filter if DefaultPatronSearchFields not set' |
|
|
185 |
); |
| 186 |
is( |
| 187 |
$filter_options[0]->get_value(), 'firstname,middle_name,surname,othernames,cardnumber,userid', |
| 188 |
'Standard filter uses hard coded list when DefaultPatronSearchFields not set' |
| 189 |
); |
| 190 |
C4::Context->set_preference( 'DefaultPatronSearchFields', "firstname,initials" ); |
| 171 |
$driver->get( $base_url . "/members/members-home.pl" ); |
191 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 172 |
@adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
192 |
@adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
| 173 |
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'); |
193 |
is( |
| 174 |
is( $adv_options[0]->get_value(), 'firstname,initials', 'Standard search uses DefaultPatronSearchFields when populated'); |
194 |
scalar @adv_options, $nb_standard_fields, |
|
|
195 |
'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' |
| 196 |
); |
| 197 |
is( |
| 198 |
$adv_options[0]->get_value(), 'firstname,initials', |
| 199 |
'Standard search uses DefaultPatronSearchFields when populated' |
| 200 |
); |
| 175 |
@filter_options = $driver->find_elements('//select[@id="searchfieldstype_filter"]/option'); |
201 |
@filter_options = $driver->find_elements('//select[@id="searchfieldstype_filter"]/option'); |
| 176 |
is( scalar @filter_options, $nb_standard_fields, 'New filter option added when DefaultPatronSearchFields is populated with a field'); |
202 |
is( |
| 177 |
is( $filter_options[0]->get_value(), 'firstname,initials', 'Standard filter uses DefaultPatronSearchFields when populated'); |
203 |
scalar @filter_options, $nb_standard_fields, |
| 178 |
C4::Context->set_preference('DefaultPatronSearchFields',"firstname,initials,horses"); |
204 |
'New filter option added when DefaultPatronSearchFields is populated with a field' |
|
|
205 |
); |
| 206 |
is( |
| 207 |
$filter_options[0]->get_value(), 'firstname,initials', |
| 208 |
'Standard filter uses DefaultPatronSearchFields when populated' |
| 209 |
); |
| 210 |
C4::Context->set_preference( 'DefaultPatronSearchFields', "firstname,initials,horses" ); |
| 179 |
$driver->get( $base_url . "/members/members-home.pl" ); |
211 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 180 |
@adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
212 |
@adv_options = $driver->find_elements('//select[@id="searchfieldstype"]/option'); |
| 181 |
@filter_options = $driver->find_elements('//select[@id="searchfieldstype_filter"]/option'); |
213 |
@filter_options = $driver->find_elements('//select[@id="searchfieldstype_filter"]/option'); |
| 182 |
is( scalar @adv_options, $nb_standard_fields, 'Invalid option not added when DefaultPatronSearchFields is populated with an invalid field'); |
214 |
is( |
| 183 |
is( scalar @filter_options, $nb_standard_fields, 'Invalid filter option not added when DefaultPatronSearchFields is populated with an invalid field'); |
215 |
scalar @adv_options, $nb_standard_fields, |
|
|
216 |
'Invalid option not added when DefaultPatronSearchFields is populated with an invalid field' |
| 217 |
); |
| 218 |
is( |
| 219 |
scalar @filter_options, $nb_standard_fields, |
| 220 |
'Invalid filter option not added when DefaultPatronSearchFields is populated with an invalid field' |
| 221 |
); |
| 222 |
|
| 184 |
# 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 |
| 185 |
C4::Context->set_preference('DefaultPatronSearchFields',""); |
224 |
C4::Context->set_preference( 'DefaultPatronSearchFields', "" ); |
| 186 |
$driver->get( $base_url . "/members/members-home.pl" ); |
225 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 187 |
$s->fill_form( { search_patron_filter => 'test_patron' } ); |
226 |
$s->fill_form( { search_patron_filter => 'test_patron' } ); |
| 188 |
$s->submit_form; |
227 |
$s->submit_form; |
| 189 |
my $first_patron = $patrons[0]; |
228 |
my $first_patron = $patrons[0]; |
| 190 |
|
229 |
|
| 191 |
$s->wait_for_ajax; |
230 |
$s->wait_for_ajax; |
| 192 |
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' ); |
| 193 |
like ($td[2]->get_text, qr[\Q$firstname\E], |
232 |
like( |
|
|
233 |
$td[2]->get_text, qr[\Q$firstname\E], |
| 194 |
'Column "Name" should be the 3rd and contain the firstname correctly filtered' |
234 |
'Column "Name" should be the 3rd and contain the firstname correctly filtered' |
| 195 |
); |
235 |
); |
| 196 |
like ($td[2]->get_text, qr[\Q$address\E], |
236 |
like( |
|
|
237 |
$td[2]->get_text, qr[\Q$address\E], |
| 197 |
'Column "Name" should be the 3rd and contain the address correctly filtered' |
238 |
'Column "Name" should be the 3rd and contain the address correctly filtered' |
| 198 |
); |
239 |
); |
| 199 |
like ($td[2]->get_text, qr[\Q$email\E], |
240 |
like( |
|
|
241 |
$td[2]->get_text, qr[\Q$email\E], |
| 200 |
'Column "Name" should be the 3rd and contain the email address correctly filtered' |
242 |
'Column "Name" should be the 3rd and contain the email address correctly filtered' |
| 201 |
); |
243 |
); |
| 202 |
is( $td[4]->get_text, $branchname, |
244 |
is( |
|
|
245 |
$td[4]->get_text, $branchname, |
| 203 |
'Column "Library" should be the 6th and contain the html tags - they have been html filtered' |
246 |
'Column "Library" should be the 6th and contain the html tags - they have been html filtered' |
| 204 |
); |
247 |
); |
| 205 |
is( $td[9]->get_text, $borrowernotes_displayed, |
248 |
is( |
|
|
249 |
$td[9]->get_text, $borrowernotes_displayed, |
| 206 |
'Column "Circ note" should be the 10th and not contain the html tags - they have not been html filtered' |
250 |
'Column "Circ note" should be the 10th and not contain the html tags - they have not been html filtered' |
| 207 |
); |
251 |
); |
| 208 |
|
252 |
|
| 209 |
$driver->find_element( |
253 |
$driver->find_element( |
| 210 |
'//a[@href="/cgi-bin/koha/members/memberentry.pl?op=modify&destination=circ&borrowernumber=' |
254 |
'//a[@href="/cgi-bin/koha/members/memberentry.pl?op=modify&destination=circ&borrowernumber=' |
| 211 |
. $first_patron->borrowernumber |
255 |
. $first_patron->borrowernumber |
| 212 |
. '"]' )->click; |
256 |
. '"]' )->click; |
| 213 |
is( |
257 |
is( |
| 214 |
$driver->get_title, |
258 |
$driver->get_title, |
| 215 |
sprintf( |
259 |
sprintf( |
| 216 |
"Modify patron %s %s %s (%s) %s (%s) (%s) › Patrons › Koha", |
260 |
"Modify patron %s %s %s (%s) %s (%s) (%s) › Patrons › Koha", |
| 217 |
$first_patron->title, $first_patron->firstname, $first_patron->middle_name, $first_patron->othernames, $first_patron->surname, $first_patron->cardnumber, |
261 |
$first_patron->title, $first_patron->firstname, $first_patron->middle_name, $first_patron->othernames, |
|
|
262 |
$first_patron->surname, $first_patron->cardnumber, |
| 218 |
$first_patron->category->description, |
263 |
$first_patron->category->description, |
| 219 |
), |
264 |
), |
| 220 |
'Page title is correct after following modification link' |
265 |
'Page title is correct after following modification link' |
|
Lines 225-237
subtest 'Search patrons' => sub {
Link Here
|
| 225 |
$s->submit_form; |
270 |
$s->submit_form; |
| 226 |
$s->wait_for_ajax; |
271 |
$s->wait_for_ajax; |
| 227 |
|
272 |
|
| 228 |
$s->driver->find_element('//*[@id="'.$table_id.'_filter"]//input')->send_keys('test_patron'); |
273 |
$s->driver->find_element( '//*[@id="' . $table_id . '_filter"]//input' )->send_keys('test_patron'); |
| 229 |
$s->wait_for_ajax; |
274 |
$s->wait_for_ajax; |
| 230 |
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' ); |
275 |
is( |
|
|
276 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->get_text, |
| 277 |
sprintf( |
| 278 |
'Showing 1 to %s of %s entries (filtered from %s total entries)', $PatronsPerPage, 26, |
| 279 |
$total_number_of_patrons |
| 280 |
), |
| 281 |
'Searching in standard brings back correct results' |
| 282 |
); |
| 231 |
|
283 |
|
| 232 |
$s->driver->find_element('//table[@id="'.$table_id.'"]//th[@data-filter="libraries"]/select/option[@value="'.$library->branchcode.'"]')->click; |
284 |
$s->driver->find_element( '//table[@id="' |
|
|
285 |
. $table_id |
| 286 |
. '"]//th[@data-filter="libraries"]/select/option[@value="' |
| 287 |
. $library->branchcode |
| 288 |
. '"]' )->click; |
| 233 |
$s->wait_for_ajax; |
289 |
$s->wait_for_ajax; |
| 234 |
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' ); |
290 |
is( |
|
|
291 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->get_text, |
| 292 |
sprintf( |
| 293 |
'Showing 1 to %s of %s entries (filtered from %s total entries)', $PatronsPerPage, 25, |
| 294 |
$total_number_of_patrons |
| 295 |
), |
| 296 |
'Filtering on library works in combination with main search' |
| 297 |
); |
| 235 |
|
298 |
|
| 236 |
# Reset the filters |
299 |
# Reset the filters |
| 237 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="clear_search"]')->click(); |
300 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="clear_search"]')->click(); |
|
Lines 239-252
subtest 'Search patrons' => sub {
Link Here
|
| 239 |
$s->wait_for_ajax; |
302 |
$s->wait_for_ajax; |
| 240 |
|
303 |
|
| 241 |
# And make sure all the patrons are present |
304 |
# And make sure all the patrons are present |
| 242 |
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' ); |
305 |
is( |
|
|
306 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->get_text, |
| 307 |
sprintf( 'Showing 1 to %s of %s entries', $PatronsPerPage, $total_number_of_patrons ), |
| 308 |
'Resetting filters works as expected' |
| 309 |
); |
| 243 |
|
310 |
|
| 244 |
# Pattern terms must be split |
311 |
# Pattern terms must be split |
| 245 |
$s->fill_form( { search_patron_filter => 'test patron' } ); |
312 |
$s->fill_form( { search_patron_filter => 'test patron' } ); |
| 246 |
$s->submit_form; |
313 |
$s->submit_form; |
| 247 |
|
314 |
|
| 248 |
$s->wait_for_ajax; |
315 |
$s->wait_for_ajax; |
| 249 |
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) ); |
316 |
is( |
|
|
317 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->get_text, |
| 318 |
sprintf( |
| 319 |
'Showing 1 to %s of %s entries (filtered from %s total entries)', $PatronsPerPage, 26, |
| 320 |
$total_number_of_patrons |
| 321 |
) |
| 322 |
); |
| 250 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="clear_search"]')->click(); |
323 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="clear_search"]')->click(); |
| 251 |
$s->submit_form; |
324 |
$s->submit_form; |
| 252 |
$s->wait_for_ajax; |
325 |
$s->wait_for_ajax; |
|
Lines 256-283
subtest 'Search patrons' => sub {
Link Here
|
| 256 |
$s->submit_form; |
329 |
$s->submit_form; |
| 257 |
$s->wait_for_ajax; |
330 |
$s->wait_for_ajax; |
| 258 |
|
331 |
|
| 259 |
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' ); |
332 |
is( |
|
|
333 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->get_text, |
| 334 |
sprintf( 'No entries to show (filtered from %s total entries)', $total_number_of_patrons ), |
| 335 |
'Searching on a non-searchable attribute returns no results' |
| 336 |
); |
| 260 |
|
337 |
|
| 261 |
# clear form |
338 |
# clear form |
| 262 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="clear_search"]')->click(); |
339 |
$driver->find_element('//form[@id="patron_search_form"]//*[@id="clear_search"]')->click(); |
|
|
340 |
|
| 263 |
# Search on searchable attribute, we expect 2 patrons |
341 |
# Search on searchable attribute, we expect 2 patrons |
| 264 |
$s->fill_form( { search_patron_filter => 'test_attr_2' } ); |
342 |
$s->fill_form( { search_patron_filter => 'test_attr_2' } ); |
| 265 |
$s->submit_form; |
343 |
$s->submit_form; |
| 266 |
$s->wait_for_ajax; |
344 |
$s->wait_for_ajax; |
| 267 |
|
345 |
|
| 268 |
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' ); |
346 |
is( |
|
|
347 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->get_text, |
| 348 |
sprintf( 'Showing 1 to %s of %s entries (filtered from %s total entries)', 2, 2, $total_number_of_patrons ), |
| 349 |
'Searching on a searchable attribute returns correct results' |
| 350 |
); |
| 269 |
|
351 |
|
| 270 |
# Refine search and search for test_patron in all the data using the DT global search |
352 |
# Refine search and search for test_patron in all the data using the DT global search |
| 271 |
# No change in result expected, still 2 patrons |
353 |
# No change in result expected, still 2 patrons |
| 272 |
$s->driver->find_element('//*[@id="'.$table_id.'_filter"]//input')->send_keys('test_patron'); |
354 |
$s->driver->find_element( '//*[@id="' . $table_id . '_filter"]//input' )->send_keys('test_patron'); |
| 273 |
$s->wait_for_ajax; |
355 |
$s->wait_for_ajax; |
| 274 |
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), 'Refining with DataTables search works to further filter the original query' ); |
356 |
is( |
|
|
357 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->get_text, |
| 358 |
sprintf( 'Showing 1 to %s of %s entries (filtered from %s total entries)', 2, 2, $total_number_of_patrons ), |
| 359 |
'Refining with DataTables search works to further filter the original query' |
| 360 |
); |
| 275 |
|
361 |
|
| 276 |
# Adding the surname of the first patron in the "Name" column |
362 |
# Adding the surname of the first patron in the "Name" column |
| 277 |
# We expect only 1 result |
363 |
# We expect only 1 result |
| 278 |
$s->driver->find_element('//table[@id="'.$table_id.'"]//input[@placeholder="Name search"]')->send_keys($patrons[0]->surname); |
364 |
$s->driver->find_element( '//table[@id="' . $table_id . '"]//input[@placeholder="Name search"]' ) |
|
|
365 |
->send_keys( $patrons[0]->surname ); |
| 279 |
$s->wait_for_ajax; |
366 |
$s->wait_for_ajax; |
| 280 |
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' ); |
367 |
is( |
|
|
368 |
$driver->find_element( '//div[@id="' . $table_id . '_info"]' )->get_text, |
| 369 |
sprintf( 'Showing 1 to %s of %s entries (filtered from %s total entries)', 1, 1, $total_number_of_patrons ), |
| 370 |
'Refining with header filters works to further filter the original query' |
| 371 |
); |
| 281 |
|
372 |
|
| 282 |
subtest 'remember_search' => sub { |
373 |
subtest 'remember_search' => sub { |
| 283 |
|
374 |
|
|
Lines 291-298
subtest 'Search patrons' => sub {
Link Here
|
| 291 |
my $patron_selected_text = $driver->find_element('//div[@id="patron_search_selected"]/span')->get_text; |
382 |
my $patron_selected_text = $driver->find_element('//div[@id="patron_search_selected"]/span')->get_text; |
| 292 |
is( $patron_selected_text, "", "Patrons selected is not displayed" ); |
383 |
is( $patron_selected_text, "", "Patrons selected is not displayed" ); |
| 293 |
|
384 |
|
| 294 |
my @checkboxes = $driver->find_elements( |
385 |
my @checkboxes = $driver->find_elements('//input[@type="checkbox"][@name="borrowernumber"]'); |
| 295 |
'//input[@type="checkbox"][@name="borrowernumber"]'); |
|
|
| 296 |
$checkboxes[2]->click; |
386 |
$checkboxes[2]->click; |
| 297 |
$patron_selected_text = $driver->find_element('//div[@id="patron_search_selected"]/span')->get_text; |
387 |
$patron_selected_text = $driver->find_element('//div[@id="patron_search_selected"]/span')->get_text; |
| 298 |
is( $patron_selected_text, "Patrons selected: 1", "One patron selected" ); |
388 |
is( $patron_selected_text, "Patrons selected: 1", "One patron selected" ); |
|
Lines 303-314
subtest 'Search patrons' => sub {
Link Here
|
| 303 |
|
393 |
|
| 304 |
$driver->find_element('//*[@id="memberresultst_next"]')->click; |
394 |
$driver->find_element('//*[@id="memberresultst_next"]')->click; |
| 305 |
$s->wait_for_ajax; |
395 |
$s->wait_for_ajax; |
| 306 |
@checkboxes = $driver->find_elements( |
396 |
@checkboxes = $driver->find_elements('//input[@type="checkbox"][@name="borrowernumber"]'); |
| 307 |
'//input[@type="checkbox"][@name="borrowernumber"]'); |
|
|
| 308 |
$checkboxes[0]->click; |
397 |
$checkboxes[0]->click; |
| 309 |
$patron_selected_text = $driver->find_element('//div[@id="patron_search_selected"]/span')->get_text; |
398 |
$patron_selected_text = $driver->find_element('//div[@id="patron_search_selected"]/span')->get_text; |
| 310 |
is( $patron_selected_text, "Patrons selected: 3", "Tree patrons are selected" ); |
399 |
is( $patron_selected_text, "Patrons selected: 3", "Three patrons are selected" ); |
| 311 |
|
|
|
| 312 |
|
400 |
|
| 313 |
# Perform another search |
401 |
# Perform another search |
| 314 |
$driver->get( $base_url . "/members/members-home.pl" ); |
402 |
$driver->get( $base_url . "/members/members-home.pl" ); |
|
Lines 316-322
subtest 'Search patrons' => sub {
Link Here
|
| 316 |
$s->submit_form; |
404 |
$s->submit_form; |
| 317 |
$s->wait_for_ajax; |
405 |
$s->wait_for_ajax; |
| 318 |
$patron_selected_text = $driver->find_element('//div[@id="patron_search_selected"]/span')->get_text; |
406 |
$patron_selected_text = $driver->find_element('//div[@id="patron_search_selected"]/span')->get_text; |
| 319 |
is( $patron_selected_text, "Patrons selected: 3", "Tree patrons still selected" ); |
407 |
is( $patron_selected_text, "Patrons selected: 3", "Three patrons still selected" ); |
| 320 |
|
408 |
|
| 321 |
$driver->find_element('//*[@id="patronlist-menu"]')->click; |
409 |
$driver->find_element('//*[@id="patronlist-menu"]')->click; |
| 322 |
$driver->find_element('//a[@class="patron-list-add"]')->click; |
410 |
$driver->find_element('//a[@class="patron-list-add"]')->click; |
|
Lines 325-344
subtest 'Search patrons' => sub {
Link Here
|
| 325 |
$driver->find_element('//button[@id="add_to_patron_list_submit"]')->click; |
413 |
$driver->find_element('//button[@id="add_to_patron_list_submit"]')->click; |
| 326 |
$s->wait_for_ajax; |
414 |
$s->wait_for_ajax; |
| 327 |
is( $driver->find_element('//*[@id="patron_list_dialog"]')->get_text, "Added 3 patrons to $patron_list_name." ); |
415 |
is( $driver->find_element('//*[@id="patron_list_dialog"]')->get_text, "Added 3 patrons to $patron_list_name." ); |
| 328 |
my $patron_list = $schema->resultset('PatronList')->search({ name => $patron_list_name })->next; |
416 |
my $patron_list = $schema->resultset('PatronList')->search( { name => $patron_list_name } )->next; |
| 329 |
is( $schema->resultset('PatronListPatron')->search({ patron_list_id => $patron_list->patron_list_id })->count, 3 ); |
417 |
is( |
|
|
418 |
$schema->resultset('PatronListPatron')->search( { patron_list_id => $patron_list->patron_list_id } )->count, |
| 419 |
3 |
| 420 |
); |
| 330 |
|
421 |
|
| 331 |
$patron_list->delete; |
422 |
$patron_list->delete; |
| 332 |
}; |
423 |
}; |
| 333 |
|
424 |
|
|
|
425 |
subtest 'filter by date of birth' => sub { |
| 426 |
plan tests => 7; |
| 427 |
|
| 428 |
C4::Context->set_preference( 'dateformat', 'metric' ); |
| 429 |
|
| 430 |
# We have a patron with date of birth=1980-06-17 => formatted as 17/06/1980 |
| 431 |
|
| 432 |
$driver->get( $base_url . "/members/members-home.pl" ); |
| 433 |
$s->fill_form( { search_patron_filter => 'test_patron' } ); |
| 434 |
$s->submit_form; |
| 435 |
$s->wait_for_ajax; |
| 436 |
|
| 437 |
$s->show_all_entries( '//div[@id="' . $table_id . '_wrapper"]' ); |
| 438 |
my $dob_search_filter = |
| 439 |
$s->driver->find_element( '//table[@id="' . $table_id . '"]//input[@placeholder="Date of birth search"]' ); |
| 440 |
|
| 441 |
$dob_search_filter->send_keys('1980'); |
| 442 |
$s->wait_for_ajax; |
| 443 |
is( is_patron_shown($patron_26), 1, 'search by correct year shows the patron' ); |
| 444 |
$dob_search_filter->clear; |
| 445 |
|
| 446 |
$dob_search_filter->send_keys('1986'); |
| 447 |
$s->wait_for_ajax; |
| 448 |
is( is_patron_shown($patron_26), 0, 'search by incorrect year does not show the patron' ); |
| 449 |
$dob_search_filter->clear; |
| 450 |
|
| 451 |
$dob_search_filter->send_keys('1980-06'); |
| 452 |
$s->wait_for_ajax; |
| 453 |
is( is_patron_shown($patron_26), 1, 'search by correct year-month shows the patron' ); |
| 454 |
$dob_search_filter->clear; |
| 455 |
|
| 456 |
$dob_search_filter->send_keys('1980-06-17'); |
| 457 |
$s->wait_for_ajax; |
| 458 |
is( is_patron_shown($patron_26), 1, 'search by correct full iso date shows the patron' ); |
| 459 |
$dob_search_filter->clear; |
| 460 |
|
| 461 |
$dob_search_filter->send_keys('1986-06-17'); |
| 462 |
$s->wait_for_ajax; |
| 463 |
is( is_patron_shown($patron_26), 0, 'search by incorrect full iso date does not show the patron' ); |
| 464 |
$dob_search_filter->clear; |
| 465 |
|
| 466 |
$dob_search_filter->send_keys('17/06/1980'); |
| 467 |
$s->wait_for_ajax; |
| 468 |
is( is_patron_shown($patron_26), 1, 'search by correct full formatted date shows the patron' ); |
| 469 |
$dob_search_filter->clear; |
| 470 |
|
| 471 |
$dob_search_filter->send_keys('17/06/1986'); |
| 472 |
$s->wait_for_ajax; |
| 473 |
is( is_patron_shown($patron_26), 0, 'search by incorrect full formatted date does not show the patron' ); |
| 474 |
$dob_search_filter->clear; |
| 475 |
}; |
| 476 |
|
| 334 |
push @cleanup, $_ for @patrons; |
477 |
push @cleanup, $_ for @patrons; |
| 335 |
push @cleanup, $library; |
478 |
push @cleanup, $library; |
| 336 |
push @cleanup, $library_2; |
479 |
push @cleanup, $library_2; |
| 337 |
push @cleanup, $patron_category; |
480 |
push @cleanup, $patron_category; |
| 338 |
push @cleanup, $attribute_type, $attribute_type_searchable; |
481 |
push @cleanup, $attribute_type, $attribute_type_searchable; |
| 339 |
C4::Context->set_preference('DefaultPatronSearchFields',$default_patron_search_fields); |
|
|
| 340 |
C4::Context->set_preference('DefaultPatronSearchMethod',$default_patron_search_method); |
| 341 |
C4::Context->set_preference('PatronsPerPage',$default_patron_per_page); |
| 342 |
|
482 |
|
| 343 |
$driver->quit(); |
483 |
$driver->quit(); |
| 344 |
}; |
484 |
}; |
| 345 |
- |
485 |
|
|
|
486 |
sub is_patron_shown { |
| 487 |
my ($patron) = @_; |
| 488 |
|
| 489 |
my @checkboxes = $driver->find_elements('//input[@type="checkbox"][@name="borrowernumber"]'); |
| 490 |
return scalar( grep { $_->get_value == $patron->borrowernumber } @checkboxes ); |
| 491 |
} |