3 # This file is part of Koha.
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.
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.
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>.
20 use Test::More tests => 50;
25 use C4::Members::Attributes;
26 use C4::Members::AttributeTypes;
29 use Koha::Patron::Categories;
32 use t::lib::TestBuilder;
36 use_ok( "C4::Utils::DataTables::Members" );
38 my $schema = Koha::Database->new->schema;
39 $schema->storage->txn_begin;
41 my $builder = t::lib::TestBuilder->new;
43 my $library = $builder->build({
47 my $patron = $builder->build_object({ class => 'Koha::Patrons', value => { flags => 1 } });
48 set_logged_in_user( $patron );
50 my $branchcode=$library->{branchcode};
52 my $john_doe = $builder->build({
55 cardnumber => '123456',
58 branchcode => $branchcode,
59 dateofbirth => '1983-03-01',
64 my $john_smith = $builder->build({
67 cardnumber => '234567',
70 branchcode => $branchcode,
71 dateofbirth => '1982-02-01',
72 userid => 'john.smith'
76 my $jane_doe = $builder->build({
79 cardnumber => '345678',
82 branchcode => $branchcode,
83 dateofbirth => '1983-03-01',
87 my $jeanpaul_dupont = $builder->build({
90 cardnumber => '456789',
91 firstname => 'Jean Paul',
93 branchcode => $branchcode,
94 dateofbirth => '1982-02-01',
95 userid => 'jeanpaul.dupont'
98 my $dupont_brown = $builder->build({
101 cardnumber => '567890',
102 firstname => 'Dupont',
104 branchcode => $branchcode,
105 dateofbirth => '1979-01-01',
106 userid => 'dupont.brown'
110 # Set common datatables params
112 iDisplayLength => 10,
117 my $search_results = C4::Utils::DataTables::Members::search({
118 searchmember => "John Doe",
119 searchfieldstype => 'standard',
120 searchtype => 'contain',
121 branchcode => $branchcode,
122 dt_params => \%dt_params
125 is( $search_results->{ iTotalDisplayRecords }, 1,
126 "John Doe has only one match on $branchcode (Bug 12595)");
128 ok( $search_results->{ patrons }[0]->{ cardnumber } eq $john_doe->{ cardnumber }
129 && ! $search_results->{ patrons }[1],
130 "John Doe is the only match (Bug 12595)");
133 $search_results = C4::Utils::DataTables::Members::search({
134 searchmember => "Jane Doe",
135 searchfieldstype => 'standard',
136 searchtype => 'contain',
137 branchcode => $branchcode,
138 dt_params => \%dt_params
141 is( $search_results->{ iTotalDisplayRecords }, 1,
142 "Jane Doe has only one match on $branchcode (Bug 12595)");
144 is( $search_results->{ patrons }[0]->{ cardnumber },
145 $jane_doe->{ cardnumber },
146 "Jane Doe is the only match (Bug 12595)");
149 $search_results = C4::Utils::DataTables::Members::search({
150 searchmember => "John",
151 searchfieldstype => 'standard',
152 searchtype => 'contain',
153 branchcode => $branchcode,
154 dt_params => \%dt_params
157 is( $search_results->{ iTotalDisplayRecords }, 2,
158 "There are two John at $branchcode");
160 is( $search_results->{ patrons }[0]->{ cardnumber },
161 $john_doe->{ cardnumber },
162 "John Doe is the first result");
164 is( $search_results->{ patrons }[1]->{ cardnumber },
165 $john_smith->{ cardnumber },
166 "John Smith is the second result");
169 $search_results = C4::Utils::DataTables::Members::search({
170 searchmember => "Doe",
171 searchfieldstype => 'standard',
172 searchtype => 'contain',
173 branchcode => $branchcode,
174 dt_params => \%dt_params
177 is( $search_results->{ iTotalDisplayRecords }, 2,
178 "There are two Doe at $branchcode");
180 is( $search_results->{ patrons }[0]->{ cardnumber },
181 $john_doe->{ cardnumber },
182 "John Doe is the first result");
184 is( $search_results->{ patrons }[1]->{ cardnumber },
185 $jane_doe->{ cardnumber },
186 "Jane Doe is the second result");
188 # Search "Smith" as surname - there is only one occurrence of Smith
189 $search_results = C4::Utils::DataTables::Members::search({
190 searchmember => "Smith",
191 searchfieldstype => 'surname',
192 searchtype => 'contain',
193 branchcode => $branchcode,
194 dt_params => \%dt_params
197 is( $search_results->{ iTotalDisplayRecords }, 1,
198 "There is one Smith at $branchcode when searching for surname");
200 is( $search_results->{ patrons }[0]->{ cardnumber },
201 $john_smith->{ cardnumber },
202 "John Smith is the first result");
204 # Search "Dupont" as surname - Dupont is used both as firstname and surname, we
205 # Should only fin d the user with Dupont as surname
206 $search_results = C4::Utils::DataTables::Members::search({
207 searchmember => "Dupont",
208 searchfieldstype => 'surname',
209 searchtype => 'contain',
210 branchcode => $branchcode,
211 dt_params => \%dt_params
214 is( $search_results->{ iTotalDisplayRecords }, 1,
215 "There is one Dupont at $branchcode when searching for surname");
217 is( $search_results->{ patrons }[0]->{ cardnumber },
218 $jeanpaul_dupont->{ cardnumber },
219 "Jean Paul Dupont is the first result");
221 # Search "Doe" as surname - Doe is used twice as surname
222 $search_results = C4::Utils::DataTables::Members::search({
223 searchmember => "Doe",
224 searchfieldstype => 'surname',
225 searchtype => 'contain',
226 branchcode => $branchcode,
227 dt_params => \%dt_params
230 is( $search_results->{ iTotalDisplayRecords }, 2,
231 "There are two Doe at $branchcode when searching for surname");
233 is( $search_results->{ patrons }[0]->{ cardnumber },
234 $john_doe->{ cardnumber },
235 "John Doe is the first result");
237 is( $search_results->{ patrons }[1]->{ cardnumber },
238 $jane_doe->{ cardnumber },
239 "Jane Doe is the second result");
242 $search_results = C4::Utils::DataTables::Members::search({
243 searchmember => "john.doe",
244 searchfieldstype => 'standard',
245 searchtype => 'contain',
246 branchcode => $branchcode,
247 dt_params => \%dt_params
250 is( $search_results->{ iTotalDisplayRecords }, 1,
251 "John Doe is found by userid, standard search (Bug 14782)");
253 $search_results = C4::Utils::DataTables::Members::search({
254 searchmember => "john.doe",
255 searchfieldstype => 'userid',
256 searchtype => 'contain',
257 branchcode => $branchcode,
258 dt_params => \%dt_params
261 is( $search_results->{ iTotalDisplayRecords }, 1,
262 "John Doe is found by userid, userid search (Bug 14782)");
264 $search_results = C4::Utils::DataTables::Members::search({
265 searchmember => "john.doe",
266 searchfieldstype => 'surname',
267 searchtype => 'contain',
268 branchcode => $branchcode,
269 dt_params => \%dt_params
272 is( $search_results->{ iTotalDisplayRecords }, 0,
273 "No members are found by userid, surname search");
275 my $attribute_type = C4::Members::AttributeTypes->new( 'ATM_1', 'my attribute type' );
276 $attribute_type->{staff_searchable} = 1;
277 $attribute_type->store;
280 C4::Members::Attributes::SetBorrowerAttributes(
281 $john_doe->{borrowernumber}, [ { code => $attribute_type->{code}, value => 'the default value for a common user' } ]
283 C4::Members::Attributes::SetBorrowerAttributes(
284 $jane_doe->{borrowernumber}, [ { code => $attribute_type->{code}, value => 'the default value for another common user' } ]
286 C4::Members::Attributes::SetBorrowerAttributes(
287 $john_smith->{borrowernumber}, [ { code => $attribute_type->{code}, value => 'Attribute which not appears even if contains "Dupont"' } ]
290 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 1);
291 $search_results = C4::Utils::DataTables::Members::search({
292 searchmember => "common user",
293 searchfieldstype => 'standard',
294 searchtype => 'contain',
295 branchcode => $branchcode,
296 dt_params => \%dt_params
299 is( $search_results->{ iTotalDisplayRecords}, 2, "There are 2 common users" );
301 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 0);
302 $search_results = C4::Utils::DataTables::Members::search({
303 searchmember => "common user",
304 searchfieldstype => 'standard',
305 searchtype => 'contain',
306 branchcode => $branchcode,
307 dt_params => \%dt_params
309 is( $search_results->{ iTotalDisplayRecords}, 0, "There are still 2 common users, but the patron attribute is not searchable " );
311 $search_results = C4::Utils::DataTables::Members::search({
312 searchmember => "Jean Paul",
313 searchfieldstype => 'standard',
314 searchtype => 'start_with',
315 branchcode => $branchcode,
316 dt_params => \%dt_params
319 is( $search_results->{ iTotalDisplayRecords }, 1,
320 "Jean Paul Dupont is found using start with and two terms search 'Jean Paul' (Bug 15252)");
322 $search_results = C4::Utils::DataTables::Members::search({
323 searchmember => "Jean Pau",
324 searchfieldstype => 'standard',
325 searchtype => 'start_with',
326 branchcode => $branchcode,
327 dt_params => \%dt_params
330 is( $search_results->{ iTotalDisplayRecords }, 1,
331 "Jean Paul Dupont is found using start with and two terms search 'Jean Pau' (Bug 15252)");
333 $search_results = C4::Utils::DataTables::Members::search({
334 searchmember => "Jea Pau",
335 searchfieldstype => 'standard',
336 searchtype => 'start_with',
337 branchcode => $branchcode,
338 dt_params => \%dt_params
341 is( $search_results->{ iTotalDisplayRecords }, 0,
342 "Jean Paul Dupont is not found using start with and two terms search 'Jea Pau' (Bug 15252)");
344 $search_results = C4::Utils::DataTables::Members::search({
345 searchmember => "Jea Pau",
346 searchfieldstype => 'standard',
347 searchtype => 'contain',
348 branchcode => $branchcode,
349 dt_params => \%dt_params
352 is( $search_results->{ iTotalDisplayRecords }, 1,
353 "Jean Paul Dupont is found using contains and two terms search 'Jea Pau' (Bug 15252)");
355 my @datetimeprefs = ("dmydot","iso","metric","us");
356 my %dates_in_pref = (
357 dmydot => ["01.02.1982","01.03.1983","01.01.1979","01.01.1988"],
358 iso => ["1982-02-01","1983-03-01","1979-01-01","1988-01-01"],
359 metric => ["01/02/1982","01/03/1983","01/01/1979","01/01/1988"],
360 us => ["02/01/1982","03/01/1983","01/01/1979","01/01/1988"],
362 foreach my $dateformloo (@datetimeprefs){
363 t::lib::Mocks::mock_preference('dateformat', $dateformloo);
364 t::lib::Mocks::mock_preference('DefaultPatronSearchFields', 'surname,firstname,othernames,userid,dateofbirth');
365 $search_results = C4::Utils::DataTables::Members::search({
366 searchmember => $dates_in_pref{$dateformloo}[0],
367 searchfieldstype => 'standard',
368 searchtype => 'contain',
369 branchcode => $branchcode,
370 dt_params => \%dt_params
373 is( $search_results->{ iTotalDisplayRecords }, 2,
374 "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[0], standard search fields plus dob works");
376 $search_results = C4::Utils::DataTables::Members::search({
377 searchmember => $dates_in_pref{$dateformloo}[2],
378 searchfieldstype => 'standard',
379 searchtype => 'contain',
380 branchcode => $branchcode,
381 dt_params => \%dt_params
384 is( $search_results->{ iTotalDisplayRecords }, 1,
385 "dateformat: $dateformloo One borrower has dob $dates_in_pref{$dateformloo}[2], standard search fields plus dob works");
387 $search_results = C4::Utils::DataTables::Members::search({
388 searchmember => $dates_in_pref{$dateformloo}[1],
389 searchfieldstype => 'dateofbirth',
390 searchtype => 'contain',
391 branchcode => $branchcode,
392 dt_params => \%dt_params
395 is( $search_results->{ iTotalDisplayRecords }, 2,
396 "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[1], dateofbirth search field works");
398 $search_results = C4::Utils::DataTables::Members::search({
399 searchmember => $dates_in_pref{$dateformloo}[3],
400 searchfieldstype => 'dateofbirth',
401 searchtype => 'contain',
402 branchcode => $branchcode,
403 dt_params => \%dt_params
406 is( $search_results->{ iTotalDisplayRecords }, 0,
407 "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], dateofbirth search field works");
409 $search_results = C4::Utils::DataTables::Members::search({
410 searchmember => $dates_in_pref{$dateformloo}[3],
411 searchfieldstype => 'standard',
412 searchtype => 'contain',
413 branchcode => $branchcode,
414 dt_params => \%dt_params
417 is( $search_results->{ iTotalDisplayRecords }, 0,
418 "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], standard search fields plus dob works");
421 # Date of birth formatting
422 t::lib::Mocks::mock_preference('dateformat', 'metric');
423 $search_results = C4::Utils::DataTables::Members::search({
424 searchmember => "01/02/1982",
425 searchfieldstype => 'dateofbirth',
426 dt_params => \%dt_params
428 is( $search_results->{ iTotalDisplayRecords }, 2,
429 "Sarching by date of birth should handle date formatted given the dateformat pref");
430 $search_results = C4::Utils::DataTables::Members::search({
431 searchmember => "1982-02-01",
432 searchfieldstype => 'dateofbirth',
433 dt_params => \%dt_params
435 is( $search_results->{ iTotalDisplayRecords }, 2,
436 "Sarching by date of birth should handle date formatted in iso");
438 subtest 'ExtendedPatronAttributes' => sub {
440 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 1);
441 $search_results = C4::Utils::DataTables::Members::search({
442 searchmember => "Dupont",
443 searchfieldstype => 'standard',
444 searchtype => 'contain',
445 branchcode => $branchcode,
446 dt_params => \%dt_params
449 is( $search_results->{ iTotalDisplayRecords }, 3,
450 "'Dupont' is contained in 2 surnames and a patron attribute. Patron attribute one should be displayed if searching in all fields (Bug 18094)");
452 $search_results = C4::Utils::DataTables::Members::search({
453 searchmember => "Dupont",
454 searchfieldstype => 'surname',
455 searchtype => 'contain',
456 branchcode => $branchcode,
457 dt_params => \%dt_params
460 is( $search_results->{ iTotalDisplayRecords }, 1,
461 "'Dupont' is contained in 2 surnames and a patron attribute. Patron attribute one should not be displayed if searching in specific fields (Bug 18094)");
465 $schema->storage->txn_rollback;
467 sub set_logged_in_user {
469 C4::Context->_new_userenv('xxx');
470 C4::Context->set_userenv(
471 $patron->borrowernumber, $patron->userid,
472 $patron->cardnumber, 'firstname',
473 'surname', $patron->library->branchcode,
474 'Midway Public Library', $patron->flags,