Bug 17829: Move GetMember to Koha::Patron
[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 => 50;
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::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 set_logged_in_user( $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         },
62 });
63
64 my $john_smith = $builder->build({
65         source => "Borrower",
66         value => {
67             cardnumber   => '234567',
68             firstname    => 'John',
69             surname      => 'Smith',
70             branchcode   => $branchcode,
71             dateofbirth  => '1982-02-01',
72             userid       => 'john.smith'
73         },
74 });
75
76 my $jane_doe = $builder->build({
77         source => "Borrower",
78         value => {
79             cardnumber   => '345678',
80             firstname    => 'Jane',
81             surname      => 'Doe',
82             branchcode   => $branchcode,
83             dateofbirth  => '1983-03-01',
84             userid       => 'jane.doe'
85         },
86 });
87 my $jeanpaul_dupont = $builder->build({
88         source => "Borrower",
89         value => {
90             cardnumber   => '456789',
91             firstname    => 'Jean Paul',
92             surname      => 'Dupont',
93             branchcode   => $branchcode,
94             dateofbirth  => '1982-02-01',
95             userid       => 'jeanpaul.dupont'
96         },
97 });
98 my $dupont_brown = $builder->build({
99         source => "Borrower",
100         value => {
101             cardnumber   => '567890',
102             firstname    => 'Dupont',
103             surname      => 'Brown',
104             branchcode   => $branchcode,
105             dateofbirth  => '1979-01-01',
106             userid       => 'dupont.brown'
107         },
108 });
109
110 # Set common datatables params
111 my %dt_params = (
112     iDisplayLength   => 10,
113     iDisplayStart    => 0
114 );
115
116 # Search "John Doe"
117 my $search_results = C4::Utils::DataTables::Members::search({
118     searchmember     => "John Doe",
119     searchfieldstype => 'standard',
120     searchtype       => 'contain',
121     branchcode       => $branchcode,
122     dt_params        => \%dt_params
123 });
124
125 is( $search_results->{ iTotalDisplayRecords }, 1,
126     "John Doe has only one match on $branchcode (Bug 12595)");
127
128 ok( $search_results->{ patrons }[0]->{ cardnumber } eq $john_doe->{ cardnumber }
129     && ! $search_results->{ patrons }[1],
130     "John Doe is the only match (Bug 12595)");
131
132 # Search "Jane Doe"
133 $search_results = C4::Utils::DataTables::Members::search({
134     searchmember     => "Jane Doe",
135     searchfieldstype => 'standard',
136     searchtype       => 'contain',
137     branchcode       => $branchcode,
138     dt_params        => \%dt_params
139 });
140
141 is( $search_results->{ iTotalDisplayRecords }, 1,
142     "Jane Doe has only one match on $branchcode (Bug 12595)");
143
144 is( $search_results->{ patrons }[0]->{ cardnumber },
145     $jane_doe->{ cardnumber },
146     "Jane Doe is the only match (Bug 12595)");
147
148 # Search "John"
149 $search_results = C4::Utils::DataTables::Members::search({
150     searchmember     => "John",
151     searchfieldstype => 'standard',
152     searchtype       => 'contain',
153     branchcode       => $branchcode,
154     dt_params        => \%dt_params
155 });
156
157 is( $search_results->{ iTotalDisplayRecords }, 2,
158     "There are two John at $branchcode");
159
160 is( $search_results->{ patrons }[0]->{ cardnumber },
161     $john_doe->{ cardnumber },
162     "John Doe is the first result");
163
164 is( $search_results->{ patrons }[1]->{ cardnumber },
165     $john_smith->{ cardnumber },
166     "John Smith is the second result");
167
168 # Search "Doe"
169 $search_results = C4::Utils::DataTables::Members::search({
170     searchmember     => "Doe",
171     searchfieldstype => 'standard',
172     searchtype       => 'contain',
173     branchcode       => $branchcode,
174     dt_params        => \%dt_params
175 });
176
177 is( $search_results->{ iTotalDisplayRecords }, 2,
178     "There are two Doe at $branchcode");
179
180 is( $search_results->{ patrons }[0]->{ cardnumber },
181     $john_doe->{ cardnumber },
182     "John Doe is the first result");
183
184 is( $search_results->{ patrons }[1]->{ cardnumber },
185     $jane_doe->{ cardnumber },
186     "Jane Doe is the second result");
187
188 # Search "Smith" as surname - there is only one occurrence of Smith
189 $search_results = C4::Utils::DataTables::Members::search({
190     searchmember     => "Smith",
191     searchfieldstype => 'surname',
192     searchtype       => 'contain',
193     branchcode       => $branchcode,
194     dt_params        => \%dt_params
195 });
196
197 is( $search_results->{ iTotalDisplayRecords }, 1,
198     "There is one Smith at $branchcode when searching for surname");
199
200 is( $search_results->{ patrons }[0]->{ cardnumber },
201     $john_smith->{ cardnumber },
202     "John Smith is the first result");
203
204 # Search "Dupont" as surname - Dupont is used both as firstname and surname, we
205 # Should only fin d the user with Dupont as surname
206 $search_results = C4::Utils::DataTables::Members::search({
207     searchmember     => "Dupont",
208     searchfieldstype => 'surname',
209     searchtype       => 'contain',
210     branchcode       => $branchcode,
211     dt_params        => \%dt_params
212 });
213
214 is( $search_results->{ iTotalDisplayRecords }, 1,
215     "There is one Dupont at $branchcode when searching for surname");
216
217 is( $search_results->{ patrons }[0]->{ cardnumber },
218     $jeanpaul_dupont->{ cardnumber },
219     "Jean Paul Dupont is the first result");
220
221 # Search "Doe" as surname - Doe is used twice as surname
222 $search_results = C4::Utils::DataTables::Members::search({
223     searchmember     => "Doe",
224     searchfieldstype => 'surname',
225     searchtype       => 'contain',
226     branchcode       => $branchcode,
227     dt_params        => \%dt_params
228 });
229
230 is( $search_results->{ iTotalDisplayRecords }, 2,
231     "There are two Doe at $branchcode when searching for surname");
232
233 is( $search_results->{ patrons }[0]->{ cardnumber },
234     $john_doe->{ cardnumber },
235     "John Doe is the first result");
236
237 is( $search_results->{ patrons }[1]->{ cardnumber },
238     $jane_doe->{ cardnumber },
239     "Jane Doe is the second result");
240
241 # Search by userid
242 $search_results = C4::Utils::DataTables::Members::search({
243     searchmember     => "john.doe",
244     searchfieldstype => 'standard',
245     searchtype       => 'contain',
246     branchcode       => $branchcode,
247     dt_params        => \%dt_params
248 });
249
250 is( $search_results->{ iTotalDisplayRecords }, 1,
251     "John Doe is found by userid, standard search (Bug 14782)");
252
253 $search_results = C4::Utils::DataTables::Members::search({
254     searchmember     => "john.doe",
255     searchfieldstype => 'userid',
256     searchtype       => 'contain',
257     branchcode       => $branchcode,
258     dt_params        => \%dt_params
259 });
260
261 is( $search_results->{ iTotalDisplayRecords }, 1,
262     "John Doe is found by userid, userid search (Bug 14782)");
263
264 $search_results = C4::Utils::DataTables::Members::search({
265     searchmember     => "john.doe",
266     searchfieldstype => 'surname',
267     searchtype       => 'contain',
268     branchcode       => $branchcode,
269     dt_params        => \%dt_params
270 });
271
272 is( $search_results->{ iTotalDisplayRecords }, 0,
273     "No members are found by userid, surname search");
274
275 my $attribute_type = C4::Members::AttributeTypes->new( 'ATM_1', 'my attribute type' );
276 $attribute_type->{staff_searchable} = 1;
277 $attribute_type->store;
278
279
280 C4::Members::Attributes::SetBorrowerAttributes(
281     $john_doe->{borrowernumber}, [ { code => $attribute_type->{code}, value => 'the default value for a common user' } ]
282 );
283 C4::Members::Attributes::SetBorrowerAttributes(
284     $jane_doe->{borrowernumber}, [ { code => $attribute_type->{code}, value => 'the default value for another common user' } ]
285 );
286 C4::Members::Attributes::SetBorrowerAttributes(
287     $john_smith->{borrowernumber}, [ { code => $attribute_type->{code}, value => 'Attribute which not appears even if contains "Dupont"' } ]
288 );
289
290 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 1);
291 $search_results = C4::Utils::DataTables::Members::search({
292     searchmember     => "common user",
293     searchfieldstype => 'standard',
294     searchtype       => 'contain',
295     branchcode       => $branchcode,
296     dt_params        => \%dt_params
297 });
298
299 is( $search_results->{ iTotalDisplayRecords}, 2, "There are 2 common users" );
300
301 t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 0);
302 $search_results = C4::Utils::DataTables::Members::search({
303     searchmember     => "common user",
304     searchfieldstype => 'standard',
305     searchtype       => 'contain',
306     branchcode       => $branchcode,
307     dt_params        => \%dt_params
308 });
309 is( $search_results->{ iTotalDisplayRecords}, 0, "There are still 2 common users, but the patron attribute is not searchable " );
310
311 $search_results = C4::Utils::DataTables::Members::search({
312     searchmember     => "Jean Paul",
313     searchfieldstype => 'standard',
314     searchtype       => 'start_with',
315     branchcode       => $branchcode,
316     dt_params        => \%dt_params
317 });
318
319 is( $search_results->{ iTotalDisplayRecords }, 1,
320     "Jean Paul Dupont is found using start with and two terms search 'Jean Paul' (Bug 15252)");
321
322 $search_results = C4::Utils::DataTables::Members::search({
323     searchmember     => "Jean Pau",
324     searchfieldstype => 'standard',
325     searchtype       => 'start_with',
326     branchcode       => $branchcode,
327     dt_params        => \%dt_params
328 });
329
330 is( $search_results->{ iTotalDisplayRecords }, 1,
331     "Jean Paul Dupont is found using start with and two terms search 'Jean Pau' (Bug 15252)");
332
333 $search_results = C4::Utils::DataTables::Members::search({
334     searchmember     => "Jea Pau",
335     searchfieldstype => 'standard',
336     searchtype       => 'start_with',
337     branchcode       => $branchcode,
338     dt_params        => \%dt_params
339 });
340
341 is( $search_results->{ iTotalDisplayRecords }, 0,
342     "Jean Paul Dupont is not found using start with and two terms search 'Jea Pau' (Bug 15252)");
343
344 $search_results = C4::Utils::DataTables::Members::search({
345     searchmember     => "Jea Pau",
346     searchfieldstype => 'standard',
347     searchtype       => 'contain',
348     branchcode       => $branchcode,
349     dt_params        => \%dt_params
350 });
351
352 is( $search_results->{ iTotalDisplayRecords }, 1,
353     "Jean Paul Dupont is found using contains and two terms search 'Jea Pau' (Bug 15252)");
354
355 my @datetimeprefs = ("dmydot","iso","metric","us");
356 my %dates_in_pref = (
357         dmydot  => ["01.02.1982","01.03.1983","01.01.1979","01.01.1988"],
358         iso     => ["1982-02-01","1983-03-01","1979-01-01","1988-01-01"],
359         metric  => ["01/02/1982","01/03/1983","01/01/1979","01/01/1988"],
360         us      => ["02/01/1982","03/01/1983","01/01/1979","01/01/1988"],
361         );
362 foreach my $dateformloo (@datetimeprefs){
363     t::lib::Mocks::mock_preference('dateformat', $dateformloo);
364     t::lib::Mocks::mock_preference('DefaultPatronSearchFields', 'surname,firstname,othernames,userid,dateofbirth');
365     $search_results = C4::Utils::DataTables::Members::search({
366         searchmember     => $dates_in_pref{$dateformloo}[0],
367         searchfieldstype => 'standard',
368         searchtype       => 'contain',
369         branchcode       => $branchcode,
370         dt_params        => \%dt_params
371     });
372
373     is( $search_results->{ iTotalDisplayRecords }, 2,
374         "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[0], standard search fields plus dob works");
375
376     $search_results = C4::Utils::DataTables::Members::search({
377         searchmember     => $dates_in_pref{$dateformloo}[2],
378         searchfieldstype => 'standard',
379         searchtype       => 'contain',
380         branchcode       => $branchcode,
381         dt_params        => \%dt_params
382     });
383
384     is( $search_results->{ iTotalDisplayRecords }, 1,
385         "dateformat: $dateformloo One borrower has dob $dates_in_pref{$dateformloo}[2], standard search fields plus dob works");
386
387     $search_results = C4::Utils::DataTables::Members::search({
388         searchmember     => $dates_in_pref{$dateformloo}[1],
389         searchfieldstype => 'dateofbirth',
390         searchtype       => 'contain',
391         branchcode       => $branchcode,
392         dt_params        => \%dt_params
393     });
394
395     is( $search_results->{ iTotalDisplayRecords }, 2,
396         "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[1], dateofbirth search field works");
397
398     $search_results = C4::Utils::DataTables::Members::search({
399         searchmember     => $dates_in_pref{$dateformloo}[3],
400         searchfieldstype => 'dateofbirth',
401         searchtype       => 'contain',
402         branchcode       => $branchcode,
403         dt_params        => \%dt_params
404     });
405
406     is( $search_results->{ iTotalDisplayRecords }, 0,
407         "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], dateofbirth search field works");
408
409     $search_results = C4::Utils::DataTables::Members::search({
410         searchmember     => $dates_in_pref{$dateformloo}[3],
411         searchfieldstype => 'standard',
412         searchtype       => 'contain',
413         branchcode       => $branchcode,
414         dt_params        => \%dt_params
415     });
416
417     is( $search_results->{ iTotalDisplayRecords }, 0,
418         "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], standard search fields plus dob works");
419 }
420
421 # Date of birth formatting
422 t::lib::Mocks::mock_preference('dateformat', 'metric');
423 $search_results = C4::Utils::DataTables::Members::search({
424     searchmember     => "01/02/1982",
425     searchfieldstype => 'dateofbirth',
426     dt_params        => \%dt_params
427 });
428 is( $search_results->{ iTotalDisplayRecords }, 2,
429     "Sarching by date of birth should handle date formatted given the dateformat pref");
430 $search_results = C4::Utils::DataTables::Members::search({
431     searchmember     => "1982-02-01",
432     searchfieldstype => 'dateofbirth',
433     dt_params        => \%dt_params
434 });
435 is( $search_results->{ iTotalDisplayRecords }, 2,
436     "Sarching by date of birth should handle date formatted in iso");
437
438 subtest 'ExtendedPatronAttributes' => sub {
439     plan tests => 2;
440     t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 1);
441     $search_results = C4::Utils::DataTables::Members::search({
442         searchmember     => "Dupont",
443         searchfieldstype => 'standard',
444         searchtype       => 'contain',
445         branchcode       => $branchcode,
446         dt_params        => \%dt_params
447     });
448
449     is( $search_results->{ iTotalDisplayRecords }, 3,
450         "'Dupont' is contained in 2 surnames and a patron attribute. Patron attribute one should be displayed if searching in all fields (Bug 18094)");
451
452     $search_results = C4::Utils::DataTables::Members::search({
453         searchmember     => "Dupont",
454         searchfieldstype => 'surname',
455         searchtype       => 'contain',
456         branchcode       => $branchcode,
457         dt_params        => \%dt_params
458     });
459
460     is( $search_results->{ iTotalDisplayRecords }, 1,
461         "'Dupont' is contained in 2 surnames and a patron attribute. Patron attribute one should not be displayed if searching in specific fields (Bug 18094)");
462 };
463
464 # End
465 $schema->storage->txn_rollback;
466
467 sub set_logged_in_user {
468     my ($patron) = @_;
469     C4::Context->_new_userenv('xxx');
470     C4::Context->set_userenv(
471         $patron->borrowernumber, $patron->userid,
472         $patron->cardnumber,     'firstname',
473         'surname',               $patron->library->branchcode,
474         'Midway Public Library', $patron->flags,
475         '',                      ''
476     );
477 }
478
479 1;