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
=> 52;
27 use Koha
::Patron
::Categories
;
30 use t
::lib
::TestBuilder
;
34 use_ok
( "C4::Utils::DataTables::Members" );
36 my $schema = Koha
::Database
->new->schema;
37 $schema->storage->txn_begin;
39 my $builder = t
::lib
::TestBuilder
->new;
41 my $library = $builder->build({
45 my $patron = $builder->build_object({ class => 'Koha::Patrons', value
=> { flags
=> 1 } });
46 t
::lib
::Mocks
::mock_userenv
({ patron
=> $patron });
48 my $branchcode=$library->{branchcode
};
50 my $john_doe = $builder->build({
53 cardnumber
=> '123456',
56 branchcode
=> $branchcode,
57 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',
77 my $jane_doe = $builder->build({
80 cardnumber
=> '345678',
83 branchcode
=> $branchcode,
84 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',
101 my $dupont_brown = $builder->build({
102 source
=> "Borrower",
104 cardnumber
=> '567890',
105 firstname
=> 'Dupont',
107 branchcode
=> $branchcode,
108 dateofbirth
=> '1979-01-01',
109 userid
=> 'dupont.brown',
114 # Set common datatables params
116 iDisplayLength
=> 10,
120 t
::lib
::Mocks
::mock_preference
('DefaultPatronSearchFields', '');
123 my $search_results = C4
::Utils
::DataTables
::Members
::search
({
124 searchmember
=> "John Doe",
125 searchfieldstype
=> 'standard',
126 searchtype
=> 'contain',
127 branchcode
=> $branchcode,
128 dt_params
=> \
%dt_params
131 is
( $search_results->{ iTotalDisplayRecords
}, 1,
132 "John Doe has only one match on $branchcode (Bug 12595)");
134 ok
( $search_results->{ patrons
}[0]->{ cardnumber
} eq $john_doe->{ cardnumber
}
135 && ! $search_results->{ patrons
}[1],
136 "John Doe is the only match (Bug 12595)");
139 $search_results = C4
::Utils
::DataTables
::Members
::search
({
140 searchmember
=> "Jane Doe",
141 searchfieldstype
=> 'standard',
142 searchtype
=> 'contain',
143 branchcode
=> $branchcode,
144 dt_params
=> \
%dt_params
147 is
( $search_results->{ iTotalDisplayRecords
}, 1,
148 "Jane Doe has only one match on $branchcode (Bug 12595)");
150 is
( $search_results->{ patrons
}[0]->{ cardnumber
},
151 $jane_doe->{ cardnumber
},
152 "Jane Doe is the only match (Bug 12595)");
155 $search_results = C4
::Utils
::DataTables
::Members
::search
({
156 searchmember
=> "John",
157 searchfieldstype
=> 'standard',
158 searchtype
=> 'contain',
159 branchcode
=> $branchcode,
160 dt_params
=> \
%dt_params
163 is
( $search_results->{ iTotalDisplayRecords
}, 2,
164 "There are two John at $branchcode");
166 is
( $search_results->{ patrons
}[0]->{ cardnumber
},
167 $john_doe->{ cardnumber
},
168 "John Doe is the first result");
170 is
( $search_results->{ patrons
}[1]->{ cardnumber
},
171 $john_smith->{ cardnumber
},
172 "John Smith is the second result");
175 $search_results = C4
::Utils
::DataTables
::Members
::search
({
176 searchmember
=> "Doe",
177 searchfieldstype
=> 'standard',
178 searchtype
=> 'contain',
179 branchcode
=> $branchcode,
180 dt_params
=> \
%dt_params
183 is
( $search_results->{ iTotalDisplayRecords
}, 2,
184 "There are two Doe at $branchcode");
186 is
( $search_results->{ patrons
}[0]->{ cardnumber
},
187 $john_doe->{ cardnumber
},
188 "John Doe is the first result");
190 is
( $search_results->{ patrons
}[1]->{ cardnumber
},
191 $jane_doe->{ cardnumber
},
192 "Jane Doe is the second result");
194 # Search "Smith" as surname - there is only one occurrence of Smith
195 $search_results = C4
::Utils
::DataTables
::Members
::search
({
196 searchmember
=> "Smith",
197 searchfieldstype
=> 'surname',
198 searchtype
=> 'contain',
199 branchcode
=> $branchcode,
200 dt_params
=> \
%dt_params
203 is
( $search_results->{ iTotalDisplayRecords
}, 1,
204 "There is one Smith at $branchcode when searching for surname");
206 is
( $search_results->{ patrons
}[0]->{ cardnumber
},
207 $john_smith->{ cardnumber
},
208 "John Smith is the first result");
210 # Search "Dupont" as surname - Dupont is used both as firstname and surname, we
211 # Should only fin d the user with Dupont as surname
212 $search_results = C4
::Utils
::DataTables
::Members
::search
({
213 searchmember
=> "Dupont",
214 searchfieldstype
=> 'surname',
215 searchtype
=> 'contain',
216 branchcode
=> $branchcode,
217 dt_params
=> \
%dt_params
220 is
( $search_results->{ iTotalDisplayRecords
}, 1,
221 "There is one Dupont at $branchcode when searching for surname");
223 is
( $search_results->{ patrons
}[0]->{ cardnumber
},
224 $jeanpaul_dupont->{ cardnumber
},
225 "Jean Paul Dupont is the first result");
227 # Search "Doe" as surname - Doe is used twice as surname
228 $search_results = C4
::Utils
::DataTables
::Members
::search
({
229 searchmember
=> "Doe",
230 searchfieldstype
=> 'surname',
231 searchtype
=> 'contain',
232 branchcode
=> $branchcode,
233 dt_params
=> \
%dt_params
236 is
( $search_results->{ iTotalDisplayRecords
}, 2,
237 "There are two Doe at $branchcode when searching for surname");
239 is
( $search_results->{ patrons
}[0]->{ cardnumber
},
240 $john_doe->{ cardnumber
},
241 "John Doe is the first result");
243 is
( $search_results->{ patrons
}[1]->{ cardnumber
},
244 $jane_doe->{ cardnumber
},
245 "Jane Doe is the second result");
248 $search_results = C4
::Utils
::DataTables
::Members
::search
({
249 searchmember
=> "john.doe",
250 searchfieldstype
=> 'standard',
251 searchtype
=> 'contain',
252 branchcode
=> $branchcode,
253 dt_params
=> \
%dt_params
256 is
( $search_results->{ iTotalDisplayRecords
}, 1,
257 "John Doe is found by userid, standard search (Bug 14782)");
259 $search_results = C4
::Utils
::DataTables
::Members
::search
({
260 searchmember
=> "john.doe",
261 searchfieldstype
=> 'userid',
262 searchtype
=> 'contain',
263 branchcode
=> $branchcode,
264 dt_params
=> \
%dt_params
267 is
( $search_results->{ iTotalDisplayRecords
}, 1,
268 "John Doe is found by userid, userid search (Bug 14782)");
270 $search_results = C4
::Utils
::DataTables
::Members
::search
({
271 searchmember
=> "john.doe",
272 searchfieldstype
=> 'surname',
273 searchtype
=> 'contain',
274 branchcode
=> $branchcode,
275 dt_params
=> \
%dt_params
278 is
( $search_results->{ iTotalDisplayRecords
}, 0,
279 "No members are found by userid, surname search");
281 my $attribute_type = Koha
::Patron
::Attribute
::Type
->new(
284 description
=> 'my attribute type',
285 staff_searchable
=> 1
289 Koha
::Patrons
->find( $john_doe->{borrowernumber
} )->extended_attributes(
292 code
=> $attribute_type->code,
293 attribute
=> 'the default value for a common user'
297 Koha
::Patrons
->find( $jane_doe->{borrowernumber
} )->extended_attributes(
300 code
=> $attribute_type->code,
301 attribute
=> 'the default value for another common user'
305 Koha
::Patrons
->find( $john_smith->{borrowernumber
} )->extended_attributes(
308 code
=> $attribute_type->code,
309 attribute
=> 'Attribute which not appears even if contains "Dupont"'
314 t
::lib
::Mocks
::mock_preference
('ExtendedPatronAttributes', 1);
315 $search_results = C4
::Utils
::DataTables
::Members
::search
({
316 searchmember
=> "common user",
317 searchfieldstype
=> 'standard',
318 searchtype
=> 'contain',
319 branchcode
=> $branchcode,
320 dt_params
=> \
%dt_params
323 is
( $search_results->{ iTotalDisplayRecords
}, 2, "There are 2 common users" );
325 t
::lib
::Mocks
::mock_preference
('ExtendedPatronAttributes', 0);
326 $search_results = C4
::Utils
::DataTables
::Members
::search
({
327 searchmember
=> "common user",
328 searchfieldstype
=> 'standard',
329 searchtype
=> 'contain',
330 branchcode
=> $branchcode,
331 dt_params
=> \
%dt_params
333 is
( $search_results->{ iTotalDisplayRecords
}, 0, "There are still 2 common users, but the patron attribute is not searchable " );
335 $search_results = C4
::Utils
::DataTables
::Members
::search
({
336 searchmember
=> "Jean Paul",
337 searchfieldstype
=> 'standard',
338 searchtype
=> 'start_with',
339 branchcode
=> $branchcode,
340 dt_params
=> \
%dt_params
343 is
( $search_results->{ iTotalDisplayRecords
}, 1,
344 "Jean Paul Dupont is found using start with and two terms search 'Jean Paul' (Bug 15252)");
346 $search_results = C4
::Utils
::DataTables
::Members
::search
({
347 searchmember
=> "Jean Pau",
348 searchfieldstype
=> 'standard',
349 searchtype
=> 'start_with',
350 branchcode
=> $branchcode,
351 dt_params
=> \
%dt_params
354 is
( $search_results->{ iTotalDisplayRecords
}, 1,
355 "Jean Paul Dupont is found using start with and two terms search 'Jean Pau' (Bug 15252)");
357 $search_results = C4
::Utils
::DataTables
::Members
::search
({
358 searchmember
=> "Jea Pau",
359 searchfieldstype
=> 'standard',
360 searchtype
=> 'start_with',
361 branchcode
=> $branchcode,
362 dt_params
=> \
%dt_params
365 is
( $search_results->{ iTotalDisplayRecords
}, 0,
366 "Jean Paul Dupont is not found using start with and two terms search 'Jea Pau' (Bug 15252)");
368 $search_results = C4
::Utils
::DataTables
::Members
::search
({
369 searchmember
=> "Jea Pau",
370 searchfieldstype
=> 'standard',
371 searchtype
=> 'contain',
372 branchcode
=> $branchcode,
373 dt_params
=> \
%dt_params
376 is
( $search_results->{ iTotalDisplayRecords
}, 1,
377 "Jean Paul Dupont is found using contains and two terms search 'Jea Pau' (Bug 15252)");
379 my @datetimeprefs = ("dmydot","iso","metric","us");
380 my %dates_in_pref = (
381 dmydot
=> ["01.02.1982","01.03.1983","01.01.1979","01.01.1988"],
382 iso
=> ["1982-02-01","1983-03-01","1979-01-01","1988-01-01"],
383 metric
=> ["01/02/1982","01/03/1983","01/01/1979","01/01/1988"],
384 us
=> ["02/01/1982","03/01/1983","01/01/1979","01/01/1988"],
386 foreach my $dateformloo (@datetimeprefs){
387 t
::lib
::Mocks
::mock_preference
('dateformat', $dateformloo);
388 t
::lib
::Mocks
::mock_preference
('DefaultPatronSearchFields', 'surname,firstname,othernames,userid,dateofbirth');
389 $search_results = C4
::Utils
::DataTables
::Members
::search
({
390 searchmember
=> $dates_in_pref{$dateformloo}[0],
391 searchfieldstype
=> 'standard',
392 searchtype
=> 'contain',
393 branchcode
=> $branchcode,
394 dt_params
=> \
%dt_params
397 is
( $search_results->{ iTotalDisplayRecords
}, 2,
398 "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[0], standard search fields plus dob works");
400 $search_results = C4
::Utils
::DataTables
::Members
::search
({
401 searchmember
=> $dates_in_pref{$dateformloo}[2],
402 searchfieldstype
=> 'standard',
403 searchtype
=> 'contain',
404 branchcode
=> $branchcode,
405 dt_params
=> \
%dt_params
408 is
( $search_results->{ iTotalDisplayRecords
}, 1,
409 "dateformat: $dateformloo One borrower has dob $dates_in_pref{$dateformloo}[2], standard search fields plus dob works");
411 $search_results = C4
::Utils
::DataTables
::Members
::search
({
412 searchmember
=> $dates_in_pref{$dateformloo}[1],
413 searchfieldstype
=> 'dateofbirth',
414 searchtype
=> 'contain',
415 branchcode
=> $branchcode,
416 dt_params
=> \
%dt_params
419 is
( $search_results->{ iTotalDisplayRecords
}, 2,
420 "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[1], dateofbirth search field works");
422 $search_results = C4
::Utils
::DataTables
::Members
::search
({
423 searchmember
=> $dates_in_pref{$dateformloo}[3],
424 searchfieldstype
=> 'dateofbirth',
425 searchtype
=> 'contain',
426 branchcode
=> $branchcode,
427 dt_params
=> \
%dt_params
430 is
( $search_results->{ iTotalDisplayRecords
}, 0,
431 "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], dateofbirth search field works");
433 $search_results = C4
::Utils
::DataTables
::Members
::search
({
434 searchmember
=> $dates_in_pref{$dateformloo}[3],
435 searchfieldstype
=> 'standard',
436 searchtype
=> 'contain',
437 branchcode
=> $branchcode,
438 dt_params
=> \
%dt_params
441 is
( $search_results->{ iTotalDisplayRecords
}, 0,
442 "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], standard search fields plus dob works");
445 # Date of birth formatting
446 t
::lib
::Mocks
::mock_preference
('dateformat', 'metric');
447 $search_results = C4
::Utils
::DataTables
::Members
::search
({
448 searchmember
=> "01/02/1982",
449 searchfieldstype
=> 'dateofbirth',
450 dt_params
=> \
%dt_params
452 is
( $search_results->{ iTotalDisplayRecords
}, 2,
453 "Sarching by date of birth should handle date formatted given the dateformat pref");
454 $search_results = C4
::Utils
::DataTables
::Members
::search
({
455 searchmember
=> "1982-02-01",
456 searchfieldstype
=> 'dateofbirth',
457 dt_params
=> \
%dt_params
459 is
( $search_results->{ iTotalDisplayRecords
}, 2,
460 "Sarching by date of birth should handle date formatted in iso");
462 subtest
'ExtendedPatronAttributes' => sub {
464 t
::lib
::Mocks
::mock_preference
('ExtendedPatronAttributes', 1);
465 $search_results = C4
::Utils
::DataTables
::Members
::search
({
466 searchmember
=> "Dupont",
467 searchfieldstype
=> 'standard',
468 searchtype
=> 'contain',
469 branchcode
=> $branchcode,
470 dt_params
=> \
%dt_params
473 is
( $search_results->{ iTotalDisplayRecords
}, 3,
474 "'Dupont' is contained in 2 surnames and a patron attribute. Patron attribute one should be displayed if searching in all fields (Bug 18094)");
476 $search_results = C4
::Utils
::DataTables
::Members
::search
({
477 searchmember
=> "Dupont",
478 searchfieldstype
=> 'surname',
479 searchtype
=> 'contain',
480 branchcode
=> $branchcode,
481 dt_params
=> \
%dt_params
484 is
( $search_results->{ iTotalDisplayRecords
}, 1,
485 "'Dupont' is contained in 2 surnames and a patron attribute. Patron attribute one should not be displayed if searching in specific fields (Bug 18094)");
488 subtest
'Search by any borrowers field (bug 17374)' => sub {
491 my $search_results = C4
::Utils
::DataTables
::Members
::search
({
492 searchmember
=> "pacman",
493 searchfieldstype
=> 'initials',
494 searchtype
=> 'contain',
495 branchcode
=> $branchcode,
496 dt_params
=> \
%dt_params
498 is
( $search_results->{ iTotalDisplayRecords
}, 1, "We find only 1 patron when searching for initials 'pacman'" );
500 is
( $search_results->{ patrons
}[0]->{ cardnumber
}, $john_doe->{cardnumber
}, "We find the correct patron when sesrching by initials" )
503 subtest
'Search with permissions' => sub {
506 my $superlibrarian = $builder->build_object(
508 class => 'Koha::Patrons',
509 value
=> { branchcode
=> $branchcode, flags
=> 1 }
512 my $librarian_with_full_permission = $builder->build_object(
514 class => 'Koha::Patrons',
515 value
=> { branchcode
=> $branchcode, flags
=> 4100 }
517 ); # 4100 = 4096 (2^12 suggestions) + 4 (2^2 catalogue)
518 my $librarian_with_subpermission = $builder->build_object(
519 { class => 'Koha::Patrons', value
=> { branchcode
=> $branchcode } } );
520 C4
::Context
->dbh->do(
521 q
|INSERT INTO user_permissions
(borrowernumber
, module_bit
, code
) VALUES
(?
,?
,?
)|,
523 $librarian_with_subpermission->borrowernumber,
528 my $search_results = C4
::Utils
::DataTables
::Members
::search
(
531 searchfieldstype
=> 'standard',
532 searchtype
=> 'contain',
533 branchcode
=> $branchcode,
535 permission
=> 'suggestions',
536 subpermission
=> 'suggestions_manage'
538 dt_params
=> { iDisplayLength
=> 3, iDisplayStart
=> 0 },
541 is
( $search_results->{iTotalDisplayRecords
},
542 3, "We find 3 patrons with suggestions_manage permission" );
544 [ sort map { $_->{borrowernumber
} } @
{ $search_results->{patrons
} } ],
546 $superlibrarian->borrowernumber,
547 $librarian_with_full_permission->borrowernumber,
548 $librarian_with_subpermission->borrowernumber
550 'We got the 3 patrons we expected'
555 $schema->storage->txn_rollback;