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 => 51;
25 use C4::Members::Attributes;
26 use C4::Members::AttributeTypes;
30 use Koha::Patron::Categories;
33 use t::lib::TestBuilder;
37 use_ok( "C4::Utils::DataTables::Members" );
39 my $schema = Koha::Database->new->schema;
40 $schema->storage->txn_begin;
42 my $builder = t::lib::TestBuilder->new;
44 my $library = $builder->build({
48 my $patron = $builder->build_object({ class => 'Koha::Patrons', value => { flags => 1 } });
49 t::lib::Mocks::mock_userenv({ patron => $patron });
51 my $branchcode=$library->{branchcode};
53 my $john_doe = $builder->build({
56 cardnumber => '123456',
59 branchcode => $branchcode,
60 dateofbirth => '1983-03-01',
66 my $john_smith = $builder->build({
69 cardnumber => '234567',
72 branchcode => $branchcode,
73 dateofbirth => '1982-02-01',
74 userid => 'john.smith'
78 my $jane_doe = $builder->build({
81 cardnumber => '345678',
84 branchcode => $branchcode,
85 dateofbirth => '1983-03-01',
89 my $jeanpaul_dupont = $builder->build({
92 cardnumber => '456789',
93 firstname => 'Jean Paul',
95 branchcode => $branchcode,
96 dateofbirth => '1982-02-01',
97 userid => 'jeanpaul.dupont'
100 my $dupont_brown = $builder->build({
101 source => "Borrower",
103 cardnumber => '567890',
104 firstname => 'Dupont',
106 branchcode => $branchcode,
107 dateofbirth => '1979-01-01',
108 userid => 'dupont.brown'
112 # Set common datatables params
114 iDisplayLength => 10,
118 t::lib::Mocks::mock_preference('DefaultPatronSearchFields', '');
121 my $search_results = C4::Utils::DataTables::Members::search({
122 searchmember => "John Doe",
123 searchfieldstype => 'standard',
124 searchtype => 'contain',
125 branchcode => $branchcode,
126 dt_params => \%dt_params
129 is( $search_results->{ iTotalDisplayRecords }, 1,
130 "John Doe has only one match on $branchcode (Bug 12595)");
132 ok( $search_results->{ patrons }[0]->{ cardnumber } eq $john_doe->{ cardnumber }
133 && ! $search_results->{ patrons }[1],
134 "John Doe is the only match (Bug 12595)");
137 $search_results = C4::Utils::DataTables::Members::search({
138 searchmember => "Jane Doe",
139 searchfieldstype => 'standard',
140 searchtype => 'contain',
141 branchcode => $branchcode,
142 dt_params => \%dt_params
145 is( $search_results->{ iTotalDisplayRecords }, 1,
146 "Jane Doe has only one match on $branchcode (Bug 12595)");
148 is( $search_results->{ patrons }[0]->{ cardnumber },
149 $jane_doe->{ cardnumber },
150 "Jane Doe is the only match (Bug 12595)");
153 $search_results = C4::Utils::DataTables::Members::search({
154 searchmember => "John",
155 searchfieldstype => 'standard',
156 searchtype => 'contain',
157 branchcode => $branchcode,
158 dt_params => \%dt_params
161 is( $search_results->{ iTotalDisplayRecords }, 2,
162 "There are two John at $branchcode");
164 is( $search_results->{ patrons }[0]->{ cardnumber },
165 $john_doe->{ cardnumber },
166 "John Doe is the first result");
168 is( $search_results->{ patrons }[1]->{ cardnumber },
169 $john_smith->{ cardnumber },
170 "John Smith is the second result");
173 $search_results = C4::Utils::DataTables::Members::search({
174 searchmember => "Doe",
175 searchfieldstype => 'standard',
176 searchtype => 'contain',
177 branchcode => $branchcode,
178 dt_params => \%dt_params
181 is( $search_results->{ iTotalDisplayRecords }, 2,
182 "There are two Doe at $branchcode");
184 is( $search_results->{ patrons }[0]->{ cardnumber },
185 $john_doe->{ cardnumber },
186 "John Doe is the first result");
188 is( $search_results->{ patrons }[1]->{ cardnumber },
189 $jane_doe->{ cardnumber },
190 "Jane Doe is the second result");
192 # Search "Smith" as surname - there is only one occurrence of Smith
193 $search_results = C4::Utils::DataTables::Members::search({
194 searchmember => "Smith",
195 searchfieldstype => 'surname',
196 searchtype => 'contain',
197 branchcode => $branchcode,
198 dt_params => \%dt_params
201 is( $search_results->{ iTotalDisplayRecords }, 1,
202 "There is one Smith at $branchcode when searching for surname");
204 is( $search_results->{ patrons }[0]->{ cardnumber },
205 $john_smith->{ cardnumber },
206 "John Smith is the first result");
208 # Search "Dupont" as surname - Dupont is used both as firstname and surname, we
209 # Should only fin d the user with Dupont as surname
210 $search_results = C4::Utils::DataTables::Members::search({
211 searchmember => "Dupont",
212 searchfieldstype => 'surname',
213 searchtype => 'contain',
214 branchcode => $branchcode,
215 dt_params => \%dt_params
218 is( $search_results->{ iTotalDisplayRecords }, 1,
219 "There is one Dupont at $branchcode when searching for surname");
221 is( $search_results->{ patrons }[0]->{ cardnumber },
222 $jeanpaul_dupont->{ cardnumber },
223 "Jean Paul Dupont is the first result");
225 # Search "Doe" as surname - Doe is used twice as surname
226 $search_results = C4::Utils::DataTables::Members::search({
227 searchmember => "Doe",
228 searchfieldstype => 'surname',
229 searchtype => 'contain',
230 branchcode => $branchcode,
231 dt_params => \%dt_params
234 is( $search_results->{ iTotalDisplayRecords }, 2,
235 "There are two Doe at $branchcode when searching for surname");
237 is( $search_results->{ patrons }[0]->{ cardnumber },
238 $john_doe->{ cardnumber },
239 "John Doe is the first result");
241 is( $search_results->{ patrons }[1]->{ cardnumber },
242 $jane_doe->{ cardnumber },
243 "Jane Doe is the second result");
246 $search_results = C4::Utils::DataTables::Members::search({
247 searchmember => "john.doe",
248 searchfieldstype => 'standard',
249 searchtype => 'contain',
250 branchcode => $branchcode,
251 dt_params => \%dt_params
254 is( $search_results->{ iTotalDisplayRecords }, 1,
255 "John Doe is found by userid, standard search (Bug 14782)");
257 $search_results = C4::Utils::DataTables::Members::search({
258 searchmember => "john.doe",
259 searchfieldstype => 'userid',
260 searchtype => 'contain',
261 branchcode => $branchcode,
262 dt_params => \%dt_params
265 is( $search_results->{ iTotalDisplayRecords }, 1,
266 "John Doe is found by userid, userid search (Bug 14782)");
268 $search_results = C4::Utils::DataTables::Members::search({
269 searchmember => "john.doe",
270 searchfieldstype => 'surname',
271 searchtype => 'contain',
272 branchcode => $branchcode,
273 dt_params => \%dt_params
276 is( $search_results->{ iTotalDisplayRecords }, 0,
277 "No members are found by userid, surname search");
279 my $attribute_type = C4::Members::AttributeTypes->new( 'ATM_1', 'my attribute type' );
280 $attribute_type->{staff_searchable} = 1;
281 $attribute_type->store;
283 Koha::Patrons->find( $john_doe->{borrowernumber} )->extended_attributes(
286 code => $attribute_type->{code},
287 attribute => 'the default value for a common user'
291 Koha::Patrons->find( $jane_doe->{borrowernumber} )->extended_attributes(
294 code => $attribute_type->{code},
295 attribute => 'the default value for another common user'
299 Koha::Patrons->find( $john_smith->{borrowernumber} )->extended_attributes(
302 code => $attribute_type->{code},
303 attribute => 'Attribute which not appears even if contains "Dupont"'
308 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 1);
309 $search_results = C4::Utils::DataTables::Members::search({
310 searchmember => "common user",
311 searchfieldstype => 'standard',
312 searchtype => 'contain',
313 branchcode => $branchcode,
314 dt_params => \%dt_params
317 is( $search_results->{ iTotalDisplayRecords}, 2, "There are 2 common users" );
319 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 0);
320 $search_results = C4::Utils::DataTables::Members::search({
321 searchmember => "common user",
322 searchfieldstype => 'standard',
323 searchtype => 'contain',
324 branchcode => $branchcode,
325 dt_params => \%dt_params
327 is( $search_results->{ iTotalDisplayRecords}, 0, "There are still 2 common users, but the patron attribute is not searchable " );
329 $search_results = C4::Utils::DataTables::Members::search({
330 searchmember => "Jean Paul",
331 searchfieldstype => 'standard',
332 searchtype => 'start_with',
333 branchcode => $branchcode,
334 dt_params => \%dt_params
337 is( $search_results->{ iTotalDisplayRecords }, 1,
338 "Jean Paul Dupont is found using start with and two terms search 'Jean Paul' (Bug 15252)");
340 $search_results = C4::Utils::DataTables::Members::search({
341 searchmember => "Jean Pau",
342 searchfieldstype => 'standard',
343 searchtype => 'start_with',
344 branchcode => $branchcode,
345 dt_params => \%dt_params
348 is( $search_results->{ iTotalDisplayRecords }, 1,
349 "Jean Paul Dupont is found using start with and two terms search 'Jean Pau' (Bug 15252)");
351 $search_results = C4::Utils::DataTables::Members::search({
352 searchmember => "Jea Pau",
353 searchfieldstype => 'standard',
354 searchtype => 'start_with',
355 branchcode => $branchcode,
356 dt_params => \%dt_params
359 is( $search_results->{ iTotalDisplayRecords }, 0,
360 "Jean Paul Dupont is not found using start with and two terms search 'Jea Pau' (Bug 15252)");
362 $search_results = C4::Utils::DataTables::Members::search({
363 searchmember => "Jea Pau",
364 searchfieldstype => 'standard',
365 searchtype => 'contain',
366 branchcode => $branchcode,
367 dt_params => \%dt_params
370 is( $search_results->{ iTotalDisplayRecords }, 1,
371 "Jean Paul Dupont is found using contains and two terms search 'Jea Pau' (Bug 15252)");
373 my @datetimeprefs = ("dmydot","iso","metric","us");
374 my %dates_in_pref = (
375 dmydot => ["01.02.1982","01.03.1983","01.01.1979","01.01.1988"],
376 iso => ["1982-02-01","1983-03-01","1979-01-01","1988-01-01"],
377 metric => ["01/02/1982","01/03/1983","01/01/1979","01/01/1988"],
378 us => ["02/01/1982","03/01/1983","01/01/1979","01/01/1988"],
380 foreach my $dateformloo (@datetimeprefs){
381 t::lib::Mocks::mock_preference('dateformat', $dateformloo);
382 t::lib::Mocks::mock_preference('DefaultPatronSearchFields', 'surname,firstname,othernames,userid,dateofbirth');
383 $search_results = C4::Utils::DataTables::Members::search({
384 searchmember => $dates_in_pref{$dateformloo}[0],
385 searchfieldstype => 'standard',
386 searchtype => 'contain',
387 branchcode => $branchcode,
388 dt_params => \%dt_params
391 is( $search_results->{ iTotalDisplayRecords }, 2,
392 "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[0], standard search fields plus dob works");
394 $search_results = C4::Utils::DataTables::Members::search({
395 searchmember => $dates_in_pref{$dateformloo}[2],
396 searchfieldstype => 'standard',
397 searchtype => 'contain',
398 branchcode => $branchcode,
399 dt_params => \%dt_params
402 is( $search_results->{ iTotalDisplayRecords }, 1,
403 "dateformat: $dateformloo One borrower has dob $dates_in_pref{$dateformloo}[2], standard search fields plus dob works");
405 $search_results = C4::Utils::DataTables::Members::search({
406 searchmember => $dates_in_pref{$dateformloo}[1],
407 searchfieldstype => 'dateofbirth',
408 searchtype => 'contain',
409 branchcode => $branchcode,
410 dt_params => \%dt_params
413 is( $search_results->{ iTotalDisplayRecords }, 2,
414 "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[1], dateofbirth search field works");
416 $search_results = C4::Utils::DataTables::Members::search({
417 searchmember => $dates_in_pref{$dateformloo}[3],
418 searchfieldstype => 'dateofbirth',
419 searchtype => 'contain',
420 branchcode => $branchcode,
421 dt_params => \%dt_params
424 is( $search_results->{ iTotalDisplayRecords }, 0,
425 "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], dateofbirth search field works");
427 $search_results = C4::Utils::DataTables::Members::search({
428 searchmember => $dates_in_pref{$dateformloo}[3],
429 searchfieldstype => 'standard',
430 searchtype => 'contain',
431 branchcode => $branchcode,
432 dt_params => \%dt_params
435 is( $search_results->{ iTotalDisplayRecords }, 0,
436 "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], standard search fields plus dob works");
439 # Date of birth formatting
440 t::lib::Mocks::mock_preference('dateformat', 'metric');
441 $search_results = C4::Utils::DataTables::Members::search({
442 searchmember => "01/02/1982",
443 searchfieldstype => 'dateofbirth',
444 dt_params => \%dt_params
446 is( $search_results->{ iTotalDisplayRecords }, 2,
447 "Sarching by date of birth should handle date formatted given the dateformat pref");
448 $search_results = C4::Utils::DataTables::Members::search({
449 searchmember => "1982-02-01",
450 searchfieldstype => 'dateofbirth',
451 dt_params => \%dt_params
453 is( $search_results->{ iTotalDisplayRecords }, 2,
454 "Sarching by date of birth should handle date formatted in iso");
456 subtest 'ExtendedPatronAttributes' => sub {
458 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 1);
459 $search_results = C4::Utils::DataTables::Members::search({
460 searchmember => "Dupont",
461 searchfieldstype => 'standard',
462 searchtype => 'contain',
463 branchcode => $branchcode,
464 dt_params => \%dt_params
467 is( $search_results->{ iTotalDisplayRecords }, 3,
468 "'Dupont' is contained in 2 surnames and a patron attribute. Patron attribute one should be displayed if searching in all fields (Bug 18094)");
470 $search_results = C4::Utils::DataTables::Members::search({
471 searchmember => "Dupont",
472 searchfieldstype => 'surname',
473 searchtype => 'contain',
474 branchcode => $branchcode,
475 dt_params => \%dt_params
478 is( $search_results->{ iTotalDisplayRecords }, 1,
479 "'Dupont' is contained in 2 surnames and a patron attribute. Patron attribute one should not be displayed if searching in specific fields (Bug 18094)");
482 subtest 'Search by any borrowers field (bug 17374)' => sub {
485 my $search_results = C4::Utils::DataTables::Members::search({
486 searchmember => "pacman",
487 searchfieldstype => 'initials',
488 searchtype => 'contain',
489 branchcode => $branchcode,
490 dt_params => \%dt_params
492 is( $search_results->{ iTotalDisplayRecords }, 1, "We find only 1 patron when searching for initials 'pacman'" );
494 is( $search_results->{ patrons }[0]->{ cardnumber }, $john_doe->{cardnumber}, "We find the correct patron when sesrching by initials" )
498 $schema->storage->txn_rollback;