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;
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 t::lib::Mocks::mock_userenv({ patron => $patron });
50 my $branchcode=$library->{branchcode};
52 my $john_doe = $builder->build({
55 cardnumber => '123456',
58 branchcode => $branchcode,
59 dateofbirth => '1983-03-01',
65 my $john_smith = $builder->build({
68 cardnumber => '234567',
71 branchcode => $branchcode,
72 dateofbirth => '1982-02-01',
73 userid => 'john.smith'
77 my $jane_doe = $builder->build({
80 cardnumber => '345678',
83 branchcode => $branchcode,
84 dateofbirth => '1983-03-01',
88 my $jeanpaul_dupont = $builder->build({
91 cardnumber => '456789',
92 firstname => 'Jean Paul',
94 branchcode => $branchcode,
95 dateofbirth => '1982-02-01',
96 userid => 'jeanpaul.dupont'
99 my $dupont_brown = $builder->build({
100 source => "Borrower",
102 cardnumber => '567890',
103 firstname => 'Dupont',
105 branchcode => $branchcode,
106 dateofbirth => '1979-01-01',
107 userid => 'dupont.brown'
111 # Set common datatables params
113 iDisplayLength => 10,
117 t::lib::Mocks::mock_preference('DefaultPatronSearchFields', '');
120 my $search_results = C4::Utils::DataTables::Members::search({
121 searchmember => "John Doe",
122 searchfieldstype => 'standard',
123 searchtype => 'contain',
124 branchcode => $branchcode,
125 dt_params => \%dt_params
128 is( $search_results->{ iTotalDisplayRecords }, 1,
129 "John Doe has only one match on $branchcode (Bug 12595)");
131 ok( $search_results->{ patrons }[0]->{ cardnumber } eq $john_doe->{ cardnumber }
132 && ! $search_results->{ patrons }[1],
133 "John Doe is the only match (Bug 12595)");
136 $search_results = C4::Utils::DataTables::Members::search({
137 searchmember => "Jane Doe",
138 searchfieldstype => 'standard',
139 searchtype => 'contain',
140 branchcode => $branchcode,
141 dt_params => \%dt_params
144 is( $search_results->{ iTotalDisplayRecords }, 1,
145 "Jane Doe has only one match on $branchcode (Bug 12595)");
147 is( $search_results->{ patrons }[0]->{ cardnumber },
148 $jane_doe->{ cardnumber },
149 "Jane Doe is the only match (Bug 12595)");
152 $search_results = C4::Utils::DataTables::Members::search({
153 searchmember => "John",
154 searchfieldstype => 'standard',
155 searchtype => 'contain',
156 branchcode => $branchcode,
157 dt_params => \%dt_params
160 is( $search_results->{ iTotalDisplayRecords }, 2,
161 "There are two John at $branchcode");
163 is( $search_results->{ patrons }[0]->{ cardnumber },
164 $john_doe->{ cardnumber },
165 "John Doe is the first result");
167 is( $search_results->{ patrons }[1]->{ cardnumber },
168 $john_smith->{ cardnumber },
169 "John Smith is the second result");
172 $search_results = C4::Utils::DataTables::Members::search({
173 searchmember => "Doe",
174 searchfieldstype => 'standard',
175 searchtype => 'contain',
176 branchcode => $branchcode,
177 dt_params => \%dt_params
180 is( $search_results->{ iTotalDisplayRecords }, 2,
181 "There are two Doe at $branchcode");
183 is( $search_results->{ patrons }[0]->{ cardnumber },
184 $john_doe->{ cardnumber },
185 "John Doe is the first result");
187 is( $search_results->{ patrons }[1]->{ cardnumber },
188 $jane_doe->{ cardnumber },
189 "Jane Doe is the second result");
191 # Search "Smith" as surname - there is only one occurrence of Smith
192 $search_results = C4::Utils::DataTables::Members::search({
193 searchmember => "Smith",
194 searchfieldstype => 'surname',
195 searchtype => 'contain',
196 branchcode => $branchcode,
197 dt_params => \%dt_params
200 is( $search_results->{ iTotalDisplayRecords }, 1,
201 "There is one Smith at $branchcode when searching for surname");
203 is( $search_results->{ patrons }[0]->{ cardnumber },
204 $john_smith->{ cardnumber },
205 "John Smith is the first result");
207 # Search "Dupont" as surname - Dupont is used both as firstname and surname, we
208 # Should only fin d the user with Dupont as surname
209 $search_results = C4::Utils::DataTables::Members::search({
210 searchmember => "Dupont",
211 searchfieldstype => 'surname',
212 searchtype => 'contain',
213 branchcode => $branchcode,
214 dt_params => \%dt_params
217 is( $search_results->{ iTotalDisplayRecords }, 1,
218 "There is one Dupont at $branchcode when searching for surname");
220 is( $search_results->{ patrons }[0]->{ cardnumber },
221 $jeanpaul_dupont->{ cardnumber },
222 "Jean Paul Dupont is the first result");
224 # Search "Doe" as surname - Doe is used twice as surname
225 $search_results = C4::Utils::DataTables::Members::search({
226 searchmember => "Doe",
227 searchfieldstype => 'surname',
228 searchtype => 'contain',
229 branchcode => $branchcode,
230 dt_params => \%dt_params
233 is( $search_results->{ iTotalDisplayRecords }, 2,
234 "There are two Doe at $branchcode when searching for surname");
236 is( $search_results->{ patrons }[0]->{ cardnumber },
237 $john_doe->{ cardnumber },
238 "John Doe is the first result");
240 is( $search_results->{ patrons }[1]->{ cardnumber },
241 $jane_doe->{ cardnumber },
242 "Jane Doe is the second result");
245 $search_results = C4::Utils::DataTables::Members::search({
246 searchmember => "john.doe",
247 searchfieldstype => 'standard',
248 searchtype => 'contain',
249 branchcode => $branchcode,
250 dt_params => \%dt_params
253 is( $search_results->{ iTotalDisplayRecords }, 1,
254 "John Doe is found by userid, standard search (Bug 14782)");
256 $search_results = C4::Utils::DataTables::Members::search({
257 searchmember => "john.doe",
258 searchfieldstype => 'userid',
259 searchtype => 'contain',
260 branchcode => $branchcode,
261 dt_params => \%dt_params
264 is( $search_results->{ iTotalDisplayRecords }, 1,
265 "John Doe is found by userid, userid search (Bug 14782)");
267 $search_results = C4::Utils::DataTables::Members::search({
268 searchmember => "john.doe",
269 searchfieldstype => 'surname',
270 searchtype => 'contain',
271 branchcode => $branchcode,
272 dt_params => \%dt_params
275 is( $search_results->{ iTotalDisplayRecords }, 0,
276 "No members are found by userid, surname search");
278 my $attribute_type = Koha::Patron::Attribute::Type->new(
281 description => 'my attribute type',
282 staff_searchable => 1
286 Koha::Patrons->find( $john_doe->{borrowernumber} )->extended_attributes(
289 code => $attribute_type->code,
290 attribute => 'the default value for a common user'
294 Koha::Patrons->find( $jane_doe->{borrowernumber} )->extended_attributes(
297 code => $attribute_type->code,
298 attribute => 'the default value for another common user'
302 Koha::Patrons->find( $john_smith->{borrowernumber} )->extended_attributes(
305 code => $attribute_type->code,
306 attribute => 'Attribute which not appears even if contains "Dupont"'
311 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 1);
312 $search_results = C4::Utils::DataTables::Members::search({
313 searchmember => "common user",
314 searchfieldstype => 'standard',
315 searchtype => 'contain',
316 branchcode => $branchcode,
317 dt_params => \%dt_params
320 is( $search_results->{ iTotalDisplayRecords}, 2, "There are 2 common users" );
322 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 0);
323 $search_results = C4::Utils::DataTables::Members::search({
324 searchmember => "common user",
325 searchfieldstype => 'standard',
326 searchtype => 'contain',
327 branchcode => $branchcode,
328 dt_params => \%dt_params
330 is( $search_results->{ iTotalDisplayRecords}, 0, "There are still 2 common users, but the patron attribute is not searchable " );
332 $search_results = C4::Utils::DataTables::Members::search({
333 searchmember => "Jean Paul",
334 searchfieldstype => 'standard',
335 searchtype => 'start_with',
336 branchcode => $branchcode,
337 dt_params => \%dt_params
340 is( $search_results->{ iTotalDisplayRecords }, 1,
341 "Jean Paul Dupont is found using start with and two terms search 'Jean Paul' (Bug 15252)");
343 $search_results = C4::Utils::DataTables::Members::search({
344 searchmember => "Jean Pau",
345 searchfieldstype => 'standard',
346 searchtype => 'start_with',
347 branchcode => $branchcode,
348 dt_params => \%dt_params
351 is( $search_results->{ iTotalDisplayRecords }, 1,
352 "Jean Paul Dupont is found using start with and two terms search 'Jean Pau' (Bug 15252)");
354 $search_results = C4::Utils::DataTables::Members::search({
355 searchmember => "Jea Pau",
356 searchfieldstype => 'standard',
357 searchtype => 'start_with',
358 branchcode => $branchcode,
359 dt_params => \%dt_params
362 is( $search_results->{ iTotalDisplayRecords }, 0,
363 "Jean Paul Dupont is not found using start with and two terms search 'Jea Pau' (Bug 15252)");
365 $search_results = C4::Utils::DataTables::Members::search({
366 searchmember => "Jea Pau",
367 searchfieldstype => 'standard',
368 searchtype => 'contain',
369 branchcode => $branchcode,
370 dt_params => \%dt_params
373 is( $search_results->{ iTotalDisplayRecords }, 1,
374 "Jean Paul Dupont is found using contains and two terms search 'Jea Pau' (Bug 15252)");
376 my @datetimeprefs = ("dmydot","iso","metric","us");
377 my %dates_in_pref = (
378 dmydot => ["01.02.1982","01.03.1983","01.01.1979","01.01.1988"],
379 iso => ["1982-02-01","1983-03-01","1979-01-01","1988-01-01"],
380 metric => ["01/02/1982","01/03/1983","01/01/1979","01/01/1988"],
381 us => ["02/01/1982","03/01/1983","01/01/1979","01/01/1988"],
383 foreach my $dateformloo (@datetimeprefs){
384 t::lib::Mocks::mock_preference('dateformat', $dateformloo);
385 t::lib::Mocks::mock_preference('DefaultPatronSearchFields', 'surname,firstname,othernames,userid,dateofbirth');
386 $search_results = C4::Utils::DataTables::Members::search({
387 searchmember => $dates_in_pref{$dateformloo}[0],
388 searchfieldstype => 'standard',
389 searchtype => 'contain',
390 branchcode => $branchcode,
391 dt_params => \%dt_params
394 is( $search_results->{ iTotalDisplayRecords }, 2,
395 "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[0], standard search fields plus dob works");
397 $search_results = C4::Utils::DataTables::Members::search({
398 searchmember => $dates_in_pref{$dateformloo}[2],
399 searchfieldstype => 'standard',
400 searchtype => 'contain',
401 branchcode => $branchcode,
402 dt_params => \%dt_params
405 is( $search_results->{ iTotalDisplayRecords }, 1,
406 "dateformat: $dateformloo One borrower has dob $dates_in_pref{$dateformloo}[2], standard search fields plus dob works");
408 $search_results = C4::Utils::DataTables::Members::search({
409 searchmember => $dates_in_pref{$dateformloo}[1],
410 searchfieldstype => 'dateofbirth',
411 searchtype => 'contain',
412 branchcode => $branchcode,
413 dt_params => \%dt_params
416 is( $search_results->{ iTotalDisplayRecords }, 2,
417 "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[1], dateofbirth search field works");
419 $search_results = C4::Utils::DataTables::Members::search({
420 searchmember => $dates_in_pref{$dateformloo}[3],
421 searchfieldstype => 'dateofbirth',
422 searchtype => 'contain',
423 branchcode => $branchcode,
424 dt_params => \%dt_params
427 is( $search_results->{ iTotalDisplayRecords }, 0,
428 "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], dateofbirth search field works");
430 $search_results = C4::Utils::DataTables::Members::search({
431 searchmember => $dates_in_pref{$dateformloo}[3],
432 searchfieldstype => 'standard',
433 searchtype => 'contain',
434 branchcode => $branchcode,
435 dt_params => \%dt_params
438 is( $search_results->{ iTotalDisplayRecords }, 0,
439 "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], standard search fields plus dob works");
442 # Date of birth formatting
443 t::lib::Mocks::mock_preference('dateformat', 'metric');
444 $search_results = C4::Utils::DataTables::Members::search({
445 searchmember => "01/02/1982",
446 searchfieldstype => 'dateofbirth',
447 dt_params => \%dt_params
449 is( $search_results->{ iTotalDisplayRecords }, 2,
450 "Sarching by date of birth should handle date formatted given the dateformat pref");
451 $search_results = C4::Utils::DataTables::Members::search({
452 searchmember => "1982-02-01",
453 searchfieldstype => 'dateofbirth',
454 dt_params => \%dt_params
456 is( $search_results->{ iTotalDisplayRecords }, 2,
457 "Sarching by date of birth should handle date formatted in iso");
459 subtest 'ExtendedPatronAttributes' => sub {
461 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 1);
462 $search_results = C4::Utils::DataTables::Members::search({
463 searchmember => "Dupont",
464 searchfieldstype => 'standard',
465 searchtype => 'contain',
466 branchcode => $branchcode,
467 dt_params => \%dt_params
470 is( $search_results->{ iTotalDisplayRecords }, 3,
471 "'Dupont' is contained in 2 surnames and a patron attribute. Patron attribute one should be displayed if searching in all fields (Bug 18094)");
473 $search_results = C4::Utils::DataTables::Members::search({
474 searchmember => "Dupont",
475 searchfieldstype => 'surname',
476 searchtype => 'contain',
477 branchcode => $branchcode,
478 dt_params => \%dt_params
481 is( $search_results->{ iTotalDisplayRecords }, 1,
482 "'Dupont' is contained in 2 surnames and a patron attribute. Patron attribute one should not be displayed if searching in specific fields (Bug 18094)");
485 subtest 'Search by any borrowers field (bug 17374)' => sub {
488 my $search_results = C4::Utils::DataTables::Members::search({
489 searchmember => "pacman",
490 searchfieldstype => 'initials',
491 searchtype => 'contain',
492 branchcode => $branchcode,
493 dt_params => \%dt_params
495 is( $search_results->{ iTotalDisplayRecords }, 1, "We find only 1 patron when searching for initials 'pacman'" );
497 is( $search_results->{ patrons }[0]->{ cardnumber }, $john_doe->{cardnumber}, "We find the correct patron when sesrching by initials" )
501 $schema->storage->txn_rollback;