Bug 20443: Remove C4::Members::AttributeTypes
[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
27 use Koha::Library;
28 use Koha::Patrons;
29 use Koha::Patron::Categories;
30
31 use t::lib::Mocks;
32 use t::lib::TestBuilder;
33
34 use Koha::Database;
35
36 use_ok( "C4::Utils::DataTables::Members" );
37
38 my $schema = Koha::Database->new->schema;
39 $schema->storage->txn_begin;
40
41 my $builder = t::lib::TestBuilder->new;
42
43 my $library = $builder->build({
44     source => "Branch",
45 });
46
47 my $patron = $builder->build_object({ class => 'Koha::Patrons', value => { flags => 1 } });
48 t::lib::Mocks::mock_userenv({ patron => $patron });
49
50 my $branchcode=$library->{branchcode};
51
52 my $john_doe = $builder->build({
53         source => "Borrower",
54         value => {
55             cardnumber   => '123456',
56             firstname    => 'John',
57             surname      => 'Doe',
58             branchcode   => $branchcode,
59             dateofbirth  => '1983-03-01',
60             userid       => 'john.doe',
61             initials     => 'pacman'
62         },
63 });
64
65 my $john_smith = $builder->build({
66         source => "Borrower",
67         value => {
68             cardnumber   => '234567',
69             firstname    => 'John',
70             surname      => 'Smith',
71             branchcode   => $branchcode,
72             dateofbirth  => '1982-02-01',
73             userid       => 'john.smith'
74         },
75 });
76
77 my $jane_doe = $builder->build({
78         source => "Borrower",
79         value => {
80             cardnumber   => '345678',
81             firstname    => 'Jane',
82             surname      => 'Doe',
83             branchcode   => $branchcode,
84             dateofbirth  => '1983-03-01',
85             userid       => 'jane.doe'
86         },
87 });
88 my $jeanpaul_dupont = $builder->build({
89         source => "Borrower",
90         value => {
91             cardnumber   => '456789',
92             firstname    => 'Jean Paul',
93             surname      => 'Dupont',
94             branchcode   => $branchcode,
95             dateofbirth  => '1982-02-01',
96             userid       => 'jeanpaul.dupont'
97         },
98 });
99 my $dupont_brown = $builder->build({
100         source => "Borrower",
101         value => {
102             cardnumber   => '567890',
103             firstname    => 'Dupont',
104             surname      => 'Brown',
105             branchcode   => $branchcode,
106             dateofbirth  => '1979-01-01',
107             userid       => 'dupont.brown'
108         },
109 });
110
111 # Set common datatables params
112 my %dt_params = (
113     iDisplayLength   => 10,
114     iDisplayStart    => 0
115 );
116
117 t::lib::Mocks::mock_preference('DefaultPatronSearchFields', '');
118
119 # Search "John Doe"
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
126 });
127
128 is( $search_results->{ iTotalDisplayRecords }, 1,
129     "John Doe has only one match on $branchcode (Bug 12595)");
130
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)");
134
135 # Search "Jane Doe"
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
142 });
143
144 is( $search_results->{ iTotalDisplayRecords }, 1,
145     "Jane Doe has only one match on $branchcode (Bug 12595)");
146
147 is( $search_results->{ patrons }[0]->{ cardnumber },
148     $jane_doe->{ cardnumber },
149     "Jane Doe is the only match (Bug 12595)");
150
151 # Search "John"
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
158 });
159
160 is( $search_results->{ iTotalDisplayRecords }, 2,
161     "There are two John at $branchcode");
162
163 is( $search_results->{ patrons }[0]->{ cardnumber },
164     $john_doe->{ cardnumber },
165     "John Doe is the first result");
166
167 is( $search_results->{ patrons }[1]->{ cardnumber },
168     $john_smith->{ cardnumber },
169     "John Smith is the second result");
170
171 # Search "Doe"
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
178 });
179
180 is( $search_results->{ iTotalDisplayRecords }, 2,
181     "There are two Doe at $branchcode");
182
183 is( $search_results->{ patrons }[0]->{ cardnumber },
184     $john_doe->{ cardnumber },
185     "John Doe is the first result");
186
187 is( $search_results->{ patrons }[1]->{ cardnumber },
188     $jane_doe->{ cardnumber },
189     "Jane Doe is the second result");
190
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
198 });
199
200 is( $search_results->{ iTotalDisplayRecords }, 1,
201     "There is one Smith at $branchcode when searching for surname");
202
203 is( $search_results->{ patrons }[0]->{ cardnumber },
204     $john_smith->{ cardnumber },
205     "John Smith is the first result");
206
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
215 });
216
217 is( $search_results->{ iTotalDisplayRecords }, 1,
218     "There is one Dupont at $branchcode when searching for surname");
219
220 is( $search_results->{ patrons }[0]->{ cardnumber },
221     $jeanpaul_dupont->{ cardnumber },
222     "Jean Paul Dupont is the first result");
223
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
231 });
232
233 is( $search_results->{ iTotalDisplayRecords }, 2,
234     "There are two Doe at $branchcode when searching for surname");
235
236 is( $search_results->{ patrons }[0]->{ cardnumber },
237     $john_doe->{ cardnumber },
238     "John Doe is the first result");
239
240 is( $search_results->{ patrons }[1]->{ cardnumber },
241     $jane_doe->{ cardnumber },
242     "Jane Doe is the second result");
243
244 # Search by userid
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
251 });
252
253 is( $search_results->{ iTotalDisplayRecords }, 1,
254     "John Doe is found by userid, standard search (Bug 14782)");
255
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
262 });
263
264 is( $search_results->{ iTotalDisplayRecords }, 1,
265     "John Doe is found by userid, userid search (Bug 14782)");
266
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
273 });
274
275 is( $search_results->{ iTotalDisplayRecords }, 0,
276     "No members are found by userid, surname search");
277
278 my $attribute_type = Koha::Patron::Attribute::Type->new(
279     {
280         code             => 'ATM_1',
281         description      => 'my attribute type',
282         staff_searchable => 1
283     }
284 )->store;
285
286 Koha::Patrons->find( $john_doe->{borrowernumber} )->extended_attributes(
287     [
288         {
289             code      => $attribute_type->code,
290             attribute => 'the default value for a common user'
291         }
292     ]
293 );
294 Koha::Patrons->find( $jane_doe->{borrowernumber} )->extended_attributes(
295     [
296         {
297             code      => $attribute_type->code,
298             attribute => 'the default value for another common user'
299         }
300     ]
301 );
302 Koha::Patrons->find( $john_smith->{borrowernumber} )->extended_attributes(
303     [
304         {
305             code      => $attribute_type->code,
306             attribute => 'Attribute which not appears even if contains "Dupont"'
307         }
308     ]
309 );
310
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
318 });
319
320 is( $search_results->{ iTotalDisplayRecords}, 2, "There are 2 common users" );
321
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
329 });
330 is( $search_results->{ iTotalDisplayRecords}, 0, "There are still 2 common users, but the patron attribute is not searchable " );
331
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
338 });
339
340 is( $search_results->{ iTotalDisplayRecords }, 1,
341     "Jean Paul Dupont is found using start with and two terms search 'Jean Paul' (Bug 15252)");
342
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
349 });
350
351 is( $search_results->{ iTotalDisplayRecords }, 1,
352     "Jean Paul Dupont is found using start with and two terms search 'Jean Pau' (Bug 15252)");
353
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
360 });
361
362 is( $search_results->{ iTotalDisplayRecords }, 0,
363     "Jean Paul Dupont is not found using start with and two terms search 'Jea Pau' (Bug 15252)");
364
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
371 });
372
373 is( $search_results->{ iTotalDisplayRecords }, 1,
374     "Jean Paul Dupont is found using contains and two terms search 'Jea Pau' (Bug 15252)");
375
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"],
382         );
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
392     });
393
394     is( $search_results->{ iTotalDisplayRecords }, 2,
395         "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[0], standard search fields plus dob works");
396
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
403     });
404
405     is( $search_results->{ iTotalDisplayRecords }, 1,
406         "dateformat: $dateformloo One borrower has dob $dates_in_pref{$dateformloo}[2], standard search fields plus dob works");
407
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
414     });
415
416     is( $search_results->{ iTotalDisplayRecords }, 2,
417         "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[1], dateofbirth search field works");
418
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
425     });
426
427     is( $search_results->{ iTotalDisplayRecords }, 0,
428         "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], dateofbirth search field works");
429
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
436     });
437
438     is( $search_results->{ iTotalDisplayRecords }, 0,
439         "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], standard search fields plus dob works");
440 }
441
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
448 });
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
455 });
456 is( $search_results->{ iTotalDisplayRecords }, 2,
457     "Sarching by date of birth should handle date formatted in iso");
458
459 subtest 'ExtendedPatronAttributes' => sub {
460     plan tests => 2;
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
468     });
469
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)");
472
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
479     });
480
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)");
483 };
484
485 subtest 'Search by any borrowers field (bug 17374)' => sub {
486     plan tests => 2;
487
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
494     });
495     is( $search_results->{ iTotalDisplayRecords }, 1, "We find only 1 patron when searching for initials 'pacman'" );
496
497     is( $search_results->{ patrons }[0]->{ cardnumber }, $john_doe->{cardnumber}, "We find the correct patron when sesrching by initials" )
498 };
499
500 # End
501 $schema->storage->txn_rollback;