Bug 20443: Remove UpdateBorrowerAttribute and SetBorrowerAttributes
[koha.git] / t / db_dependent / Utils / Datatables_Members.t
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
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.
9 #
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.
14 #
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>.
17
18 use Modern::Perl;
19
20 use Test::More tests => 51;
21
22 use C4::Context;
23 use C4::Members;
24
25 use C4::Members::Attributes;
26 use C4::Members::AttributeTypes;
27
28 use Koha::Library;
29 use Koha::Patrons;
30 use Koha::Patron::Categories;
31
32 use t::lib::Mocks;
33 use t::lib::TestBuilder;
34
35 use Koha::Database;
36
37 use_ok( "C4::Utils::DataTables::Members" );
38
39 my $schema = Koha::Database->new->schema;
40 $schema->storage->txn_begin;
41
42 my $builder = t::lib::TestBuilder->new;
43
44 my $library = $builder->build({
45     source => "Branch",
46 });
47
48 my $patron = $builder->build_object({ class => 'Koha::Patrons', value => { flags => 1 } });
49 t::lib::Mocks::mock_userenv({ patron => $patron });
50
51 my $branchcode=$library->{branchcode};
52
53 my $john_doe = $builder->build({
54         source => "Borrower",
55         value => {
56             cardnumber   => '123456',
57             firstname    => 'John',
58             surname      => 'Doe',
59             branchcode   => $branchcode,
60             dateofbirth  => '1983-03-01',
61             userid       => 'john.doe',
62             initials     => 'pacman'
63         },
64 });
65
66 my $john_smith = $builder->build({
67         source => "Borrower",
68         value => {
69             cardnumber   => '234567',
70             firstname    => 'John',
71             surname      => 'Smith',
72             branchcode   => $branchcode,
73             dateofbirth  => '1982-02-01',
74             userid       => 'john.smith'
75         },
76 });
77
78 my $jane_doe = $builder->build({
79         source => "Borrower",
80         value => {
81             cardnumber   => '345678',
82             firstname    => 'Jane',
83             surname      => 'Doe',
84             branchcode   => $branchcode,
85             dateofbirth  => '1983-03-01',
86             userid       => 'jane.doe'
87         },
88 });
89 my $jeanpaul_dupont = $builder->build({
90         source => "Borrower",
91         value => {
92             cardnumber   => '456789',
93             firstname    => 'Jean Paul',
94             surname      => 'Dupont',
95             branchcode   => $branchcode,
96             dateofbirth  => '1982-02-01',
97             userid       => 'jeanpaul.dupont'
98         },
99 });
100 my $dupont_brown = $builder->build({
101         source => "Borrower",
102         value => {
103             cardnumber   => '567890',
104             firstname    => 'Dupont',
105             surname      => 'Brown',
106             branchcode   => $branchcode,
107             dateofbirth  => '1979-01-01',
108             userid       => 'dupont.brown'
109         },
110 });
111
112 # Set common datatables params
113 my %dt_params = (
114     iDisplayLength   => 10,
115     iDisplayStart    => 0
116 );
117
118 t::lib::Mocks::mock_preference('DefaultPatronSearchFields', '');
119
120 # Search "John Doe"
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
127 });
128
129 is( $search_results->{ iTotalDisplayRecords }, 1,
130     "John Doe has only one match on $branchcode (Bug 12595)");
131
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)");
135
136 # Search "Jane Doe"
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
143 });
144
145 is( $search_results->{ iTotalDisplayRecords }, 1,
146     "Jane Doe has only one match on $branchcode (Bug 12595)");
147
148 is( $search_results->{ patrons }[0]->{ cardnumber },
149     $jane_doe->{ cardnumber },
150     "Jane Doe is the only match (Bug 12595)");
151
152 # Search "John"
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
159 });
160
161 is( $search_results->{ iTotalDisplayRecords }, 2,
162     "There are two John at $branchcode");
163
164 is( $search_results->{ patrons }[0]->{ cardnumber },
165     $john_doe->{ cardnumber },
166     "John Doe is the first result");
167
168 is( $search_results->{ patrons }[1]->{ cardnumber },
169     $john_smith->{ cardnumber },
170     "John Smith is the second result");
171
172 # Search "Doe"
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
179 });
180
181 is( $search_results->{ iTotalDisplayRecords }, 2,
182     "There are two Doe at $branchcode");
183
184 is( $search_results->{ patrons }[0]->{ cardnumber },
185     $john_doe->{ cardnumber },
186     "John Doe is the first result");
187
188 is( $search_results->{ patrons }[1]->{ cardnumber },
189     $jane_doe->{ cardnumber },
190     "Jane Doe is the second result");
191
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
199 });
200
201 is( $search_results->{ iTotalDisplayRecords }, 1,
202     "There is one Smith at $branchcode when searching for surname");
203
204 is( $search_results->{ patrons }[0]->{ cardnumber },
205     $john_smith->{ cardnumber },
206     "John Smith is the first result");
207
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
216 });
217
218 is( $search_results->{ iTotalDisplayRecords }, 1,
219     "There is one Dupont at $branchcode when searching for surname");
220
221 is( $search_results->{ patrons }[0]->{ cardnumber },
222     $jeanpaul_dupont->{ cardnumber },
223     "Jean Paul Dupont is the first result");
224
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
232 });
233
234 is( $search_results->{ iTotalDisplayRecords }, 2,
235     "There are two Doe at $branchcode when searching for surname");
236
237 is( $search_results->{ patrons }[0]->{ cardnumber },
238     $john_doe->{ cardnumber },
239     "John Doe is the first result");
240
241 is( $search_results->{ patrons }[1]->{ cardnumber },
242     $jane_doe->{ cardnumber },
243     "Jane Doe is the second result");
244
245 # Search by userid
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
252 });
253
254 is( $search_results->{ iTotalDisplayRecords }, 1,
255     "John Doe is found by userid, standard search (Bug 14782)");
256
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
263 });
264
265 is( $search_results->{ iTotalDisplayRecords }, 1,
266     "John Doe is found by userid, userid search (Bug 14782)");
267
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
274 });
275
276 is( $search_results->{ iTotalDisplayRecords }, 0,
277     "No members are found by userid, surname search");
278
279 my $attribute_type = C4::Members::AttributeTypes->new( 'ATM_1', 'my attribute type' );
280 $attribute_type->{staff_searchable} = 1;
281 $attribute_type->store;
282
283 Koha::Patrons->find( $john_doe->{borrowernumber} )->extended_attributes(
284     [
285         {
286             code      => $attribute_type->{code},
287             attribute => 'the default value for a common user'
288         }
289     ]
290 );
291 Koha::Patrons->find( $jane_doe->{borrowernumber} )->extended_attributes(
292     [
293         {
294             code      => $attribute_type->{code},
295             attribute => 'the default value for another common user'
296         }
297     ]
298 );
299 Koha::Patrons->find( $john_smith->{borrowernumber} )->extended_attributes(
300     [
301         {
302             code      => $attribute_type->{code},
303             attribute => 'Attribute which not appears even if contains "Dupont"'
304         }
305     ]
306 );
307
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
315 });
316
317 is( $search_results->{ iTotalDisplayRecords}, 2, "There are 2 common users" );
318
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
326 });
327 is( $search_results->{ iTotalDisplayRecords}, 0, "There are still 2 common users, but the patron attribute is not searchable " );
328
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
335 });
336
337 is( $search_results->{ iTotalDisplayRecords }, 1,
338     "Jean Paul Dupont is found using start with and two terms search 'Jean Paul' (Bug 15252)");
339
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
346 });
347
348 is( $search_results->{ iTotalDisplayRecords }, 1,
349     "Jean Paul Dupont is found using start with and two terms search 'Jean Pau' (Bug 15252)");
350
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
357 });
358
359 is( $search_results->{ iTotalDisplayRecords }, 0,
360     "Jean Paul Dupont is not found using start with and two terms search 'Jea Pau' (Bug 15252)");
361
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
368 });
369
370 is( $search_results->{ iTotalDisplayRecords }, 1,
371     "Jean Paul Dupont is found using contains and two terms search 'Jea Pau' (Bug 15252)");
372
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"],
379         );
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
389     });
390
391     is( $search_results->{ iTotalDisplayRecords }, 2,
392         "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[0], standard search fields plus dob works");
393
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
400     });
401
402     is( $search_results->{ iTotalDisplayRecords }, 1,
403         "dateformat: $dateformloo One borrower has dob $dates_in_pref{$dateformloo}[2], standard search fields plus dob works");
404
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
411     });
412
413     is( $search_results->{ iTotalDisplayRecords }, 2,
414         "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[1], dateofbirth search field works");
415
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
422     });
423
424     is( $search_results->{ iTotalDisplayRecords }, 0,
425         "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], dateofbirth search field works");
426
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
433     });
434
435     is( $search_results->{ iTotalDisplayRecords }, 0,
436         "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], standard search fields plus dob works");
437 }
438
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
445 });
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
452 });
453 is( $search_results->{ iTotalDisplayRecords }, 2,
454     "Sarching by date of birth should handle date formatted in iso");
455
456 subtest 'ExtendedPatronAttributes' => sub {
457     plan tests => 2;
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
465     });
466
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)");
469
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
476     });
477
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)");
480 };
481
482 subtest 'Search by any borrowers field (bug 17374)' => sub {
483     plan tests => 2;
484
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
491     });
492     is( $search_results->{ iTotalDisplayRecords }, 1, "We find only 1 patron when searching for initials 'pacman'" );
493
494     is( $search_results->{ patrons }[0]->{ cardnumber }, $john_doe->{cardnumber}, "We find the correct patron when sesrching by initials" )
495 };
496
497 # End
498 $schema->storage->txn_rollback;