Bug 35027: Add 'hold' to patron activity triggers
[koha.git] / t / db_dependent / Koha.t
1 #!/usr/bin/perl
2 #
3 # This is to test C4/Koha
4 # It requires a working Koha database with the sample data
5
6 use Modern::Perl;
7 use Test::More tests => 6;
8 use Test::MockModule;
9 use Test::Warn;
10 use Test::Deep;
11
12 use t::lib::TestBuilder;
13
14 use C4::Context;
15 use Koha::Database;
16 use Koha::AuthorisedValue;
17 use Koha::AuthorisedValueCategories;
18 use Koha::Libraries;
19
20 BEGIN {
21     use_ok(
22         'C4::Koha',
23         qw( GetAuthorisedValues GetItemTypesCategorized xml_escape GetVariationsOfISBN GetVariationsOfISBNs GetVariationsOfISSN GetVariationsOfISSNs )
24     );
25 }
26
27 my $schema  = Koha::Database->new->schema;
28 $schema->storage->txn_begin;
29 my $builder = t::lib::TestBuilder->new;
30 my $dbh = C4::Context->dbh;
31
32 our $itype_1 = $builder->build({ source => 'Itemtype' });
33
34 subtest 'Authorized Values Tests' => sub {
35     plan tests => 4;
36
37     my $data = {
38         category            => 'CATEGORY',
39         authorised_value    => 'AUTHORISED_VALUE',
40         lib                 => 'LIB',
41         lib_opac            => 'LIBOPAC',
42         imageurl            => 'IMAGEURL'
43     };
44
45     my $avc = Koha::AuthorisedValueCategories->find($data->{category});
46     Koha::AuthorisedValueCategory->new({ category_name => $data->{category} })->store unless $avc;
47 # Insert an entry into authorised_value table
48     my $insert_success = Koha::AuthorisedValue->new(
49         {   category         => $data->{category},
50             authorised_value => $data->{authorised_value},
51             lib              => $data->{lib},
52             lib_opac         => $data->{lib_opac},
53             imageurl         => $data->{imageurl}
54         }
55     )->store;
56     ok( $insert_success, "Insert data in database" );
57
58
59 # Clean up
60     if($insert_success){
61         my $query = "DELETE FROM authorised_values WHERE category=? AND authorised_value=? AND lib=? AND lib_opac=? AND imageurl=?;";
62         my $sth = $dbh->prepare($query);
63         $sth->execute($data->{category}, $data->{authorised_value}, $data->{lib}, $data->{lib_opac}, $data->{imageurl});
64     }
65
66     Koha::AuthorisedValueCategory->new({ category_name => 'BUG10656' })->store;
67     Koha::AuthorisedValue->new(
68         {   category         => 'BUG10656',
69             authorised_value => 'ZZZ',
70             lib              => 'Z_STAFF',
71             lib_opac         => 'A_PUBLIC',
72             imageurl         => ''
73         }
74     )->store;
75     Koha::AuthorisedValue->new(
76         {   category         => 'BUG10656',
77             authorised_value => 'AAA',
78             lib              => 'A_STAFF',
79             lib_opac         => 'Z_PUBLIC',
80             imageurl         => ''
81         }
82     )->store;
83
84     # the next one sets lib_opac to NULL; in that case, the staff
85     # display value is meant to be used.
86     Koha::AuthorisedValue->new(
87         {   category         => 'BUG10656',
88             authorised_value => 'DDD',
89             lib              => 'D_STAFF',
90             lib_opac         => undef,
91             imageurl         => ''
92         }
93     )->store;
94
95     my $authvals = GetAuthorisedValues('BUG10656');
96     cmp_deeply(
97         $authvals,
98         [
99             {
100                 id => ignore(),
101                 category => 'BUG10656',
102                 authorised_value => 'AAA',
103                 lib => 'A_STAFF',
104                 lib_opac => 'Z_PUBLIC',
105                 imageurl => '',
106             },
107             {
108                 id => ignore(),
109                 category => 'BUG10656',
110                 authorised_value => 'DDD',
111                 lib => 'D_STAFF',
112                 lib_opac => undef,
113                 imageurl => '',
114             },
115             {
116                 id => ignore(),
117                 category => 'BUG10656',
118                 authorised_value => 'ZZZ',
119                 lib => 'Z_STAFF',
120                 lib_opac => 'A_PUBLIC',
121                 imageurl => '',
122             },
123         ],
124         'list of authorised values in staff mode sorted by staff label (bug 10656)'
125     );
126     $authvals = GetAuthorisedValues('BUG10656', 1);
127     cmp_deeply(
128         $authvals,
129         [
130             {
131                 id => ignore(),
132                 category => 'BUG10656',
133                 authorised_value => 'ZZZ',
134                 lib => 'A_PUBLIC',
135                 lib_opac => 'A_PUBLIC',
136                 imageurl => '',
137             },
138             {
139                 id => ignore(),
140                 category => 'BUG10656',
141                 authorised_value => 'DDD',
142                 lib => 'D_STAFF',
143                 lib_opac => undef,
144                 imageurl => '',
145             },
146             {
147                 id => ignore(),
148                 category => 'BUG10656',
149                 authorised_value => 'AAA',
150                 lib => 'Z_PUBLIC',
151                 lib_opac => 'Z_PUBLIC',
152                 imageurl => '',
153             },
154         ],
155         'list of authorised values in OPAC mode sorted by OPAC label (bug 10656)'
156     );
157
158     warning_is { GetAuthorisedValues() } [], 'No warning when no parameter passed to GetAuthorisedValues';
159
160 };
161
162 subtest 'isbn tests' => sub {
163     plan tests => 29;
164
165     my $isbn13  = "9780330356473";
166     my $isbn13D = "978-0-330-35647-3";
167     my $isbn10  = "033035647X";
168     my $isbn10D = "0-330-35647-X";
169
170     my $undef = undef;
171     is( xml_escape($undef), '', 'xml_escape() returns empty string on undef input' );
172     my $str = q{'"&<>'};
173     is( xml_escape($str), '&apos;&quot;&amp;&lt;&gt;&apos;', 'xml_escape() works as expected' );
174     is( $str,             q{'"&<>'},                         '... and does not change input in place' );
175
176     is( C4::Koha::_isbn_cleanup('0-590-35340-3'),     '0590353403', '_isbn_cleanup removes hyphens' );
177     is( C4::Koha::_isbn_cleanup('0590353403 (pbk.)'), '0590353403', '_isbn_cleanup removes parenthetical' );
178     is( C4::Koha::_isbn_cleanup('978-0-321-49694-2'), '0321496949', '_isbn_cleanup converts ISBN-13 to ISBN-10' );
179
180     is(
181         C4::Koha::NormalizeISBN( { isbn => '978-0-321-49694-2 (pbk.)', format => 'ISBN-10', strip_hyphens => 1 } ),
182         '0321496949', 'Test NormalizeISBN with all features enabled'
183     );
184
185     my @isbns = qw/ 978-0-321-49694-2 0-321-49694-9 978-0-321-49694-2 0321496949 9780321496942/;
186     is(
187         join( '|', @isbns ), join( '|', GetVariationsOfISBN('978-0-321-49694-2 (pbk.)') ),
188         'GetVariationsOfISBN returns all variations'
189     );
190
191     is(
192         join( '|', @isbns ), join( '|', GetVariationsOfISBNs('978-0-321-49694-2 (pbk.)') ),
193         'GetVariationsOfISBNs returns all variations'
194     );
195
196     my $isbn;
197     eval {
198         $isbn = C4::Koha::NormalizeISBN(
199             { isbn => '0788893777 (2 DVD 45th ed)', format => 'ISBN-10', strip_hyphens => 1 } );
200     };
201     ok( $@ eq '', 'NormalizeISBN does not throw exception when parsing invalid ISBN (bug 12243)' );
202     $isbn = C4::Koha::NormalizeISBN(
203         { isbn => '0788893777 (2 DVD 45th ed)', format => 'ISBN-10', strip_hyphens => 1, return_invalid => 1 } );
204     is(
205         $isbn, '0788893777 (2 DVD 45th ed)',
206         'NormalizeISBN returns original string when converting to ISBN10 an ISBN starting with 979 (bug 13167)'
207     );
208
209     eval {
210         $isbn = C4::Koha::NormalizeISBN( { isbn => '979-10-90085-00-8', format => 'ISBN-10', strip_hyphens => 1 } );
211     };
212     ok(
213         $@ eq '',
214         'NormalizeISBN does not throw exception when converting to ISBN10 an ISBN starting with 979 (bug 13167)'
215     );
216     ok( !defined $isbn, 'NormalizeISBN returns undef when converting to ISBN10 an ISBN starting with 979 (bug 13167)' );
217
218     @isbns = GetVariationsOfISBNs('abc');
219     is( @isbns == 1 && $isbns[0] eq 'abc', 1, 'The unaltered version should be returned if invalid' );
220
221     is(
222         C4::Koha::GetNormalizedISBN('9780062059994 (hardcover bdg.) | 0062059998 (hardcover bdg.)'), '0062059998',
223         'Test GetNormalizedISBN'
224     );
225     is(
226         C4::Koha::GetNormalizedISBN(
227             '9780385753067 (trade) | 0385753063 (trade) | 9780385753074 (lib. bdg.) | 0385753071 (lib. bdg.)'),
228         '0385753063',
229         'Test GetNormalizedISBN'
230     );
231     is(
232         C4::Koha::GetNormalizedISBN('9781432829162 (hardcover) | 1432829165 (hardcover)'), '1432829165',
233         'Test GetNormalizedISBN'
234     );
235     is(
236         C4::Koha::GetNormalizedISBN('9780062063625 (hardcover) | 9780062063632 | 0062063634'), '0062063626',
237         'Test GetNormalizedISBN'
238     );
239     is( C4::Koha::GetNormalizedISBN('9780062059932 (hardback)'), '0062059939', 'Test GetNormalizedISBN' );
240     is(
241         C4::Koha::GetNormalizedISBN(
242             '9780316370318 (hardback) | 9780316376266 (special edition hardcover) | 9780316405454 (international paperback edition)'
243         ),
244         '0316370312',
245         'Test GetNormalizedISBN'
246     );
247     is(
248         C4::Koha::GetNormalizedISBN('9781595148032 (hbk.) | 1595148035 (hbk.)'), '1595148035',
249         'Test GetNormalizedISBN'
250     );
251     is(
252         C4::Koha::GetNormalizedISBN('9780062349859 | 0062349856 | 9780062391308 | 0062391305'), '0062349856',
253         'Test GetNormalizedISBN'
254     );
255     is(
256         C4::Koha::GetNormalizedISBN(
257             '9781250075345 (hardcover) | 1250075343 (hardcover) | 9781250049872 (trade pbk.) | 1250049873 (trade pbk.)'
258         ),
259         '1250075343',
260         'Test GetNormalizedISBN'
261     );
262     is( C4::Koha::GetNormalizedISBN('9781250067128 | 125006712X'), '125006712X', 'Test GetNormalizedISBN' );
263     is( C4::Koha::GetNormalizedISBN('9780373211463 | 0373211465'), '0373211465', 'Test GetNormalizedISBN' );
264
265     is( C4::Koha::GetNormalizedUPC(), undef, 'GetNormalizedUPC should return undef if no record is passed' );
266     is(
267         C4::Koha::GetNormalizedISBN(), undef,
268         'GetNormalizedISBN should return undef if no record and no isbn are passed'
269     );
270     is(
271         C4::Koha::GetNormalizedEAN(), undef,
272         'GetNormalizedEAN should return undef if no record and no isbn are passed'
273     );
274     is(
275         C4::Koha::GetNormalizedOCLCNumber(), undef,
276         'GetNormalizedOCLCNumber should return undef if no record and no isbn are passed'
277     );
278 };
279
280 subtest 'issn stuff' => sub {
281     plan tests => 7;
282
283     is(
284         C4::Koha::NormalizeISSN( { issn => '0024-9319', strip_hyphen => 1 } ), '00249319',
285         'Test NormalizeISSN with all features enabled'
286     );
287     is(
288         C4::Koha::NormalizeISSN( { issn => '0024-9319', strip_hyphen => 0 } ), '0024-9319',
289         'Test NormalizeISSN with all features enabled'
290     );
291
292     my @issns = qw/ 0024-9319 00249319 /;
293     is(
294         join( '|', @issns ), join( '|', GetVariationsOfISSN('0024-9319') ),
295         'GetVariationsOfISSN returns all variations'
296     );
297     is(
298         join( '|', @issns ), join( '|', GetVariationsOfISSNs('0024-9319') ),
299         'GetVariationsOfISSNs returns all variations'
300     );
301
302     my $issn;
303     eval { $issn = C4::Koha::NormalizeISSN( { issn => '1234-5678', strip_hyphen => 1 } ); };
304     ok( $@ eq '', 'NormalizeISSN does not throw exception when parsing invalid ISSN' );
305
306     @issns = GetVariationsOfISSNs('abc');
307     is( $issns[0],      'abc', 'Original ISSN passed through even if invalid' );
308     is( scalar(@issns), 1,     'zero additional variations returned of invalid ISSN' );
309 };
310
311 subtest 'getFacets() tests' => sub {
312     plan tests => 4;
313
314     my $count          = 1;
315     my $library_module = Test::MockModule->new('Koha::Libraries');
316     $library_module->mock( 'count', sub { return $count } );
317
318     is( Koha::Libraries->search->count, 1, 'There should be only 1 library (singleBranchMode on)' );
319     my $facets = C4::Koha::getFacets();
320     is(
321         scalar( grep { defined $_->{idx} && $_->{idx} eq 'location' } @$facets ),
322         1,
323         'location facet present with singleBranchMode on (bug 10078)'
324     );
325
326     $count = 3;    # more libraries..
327     is( Koha::Libraries->search->count, 3, 'There should be more than 1 library (singleBranchMode off)' );
328
329     $facets = C4::Koha::getFacets();
330     is(
331         scalar( grep { defined $_->{idx} && $_->{idx} eq 'location' } @$facets ),
332         1,
333         'location facet present with singleBranchMode off (bug 10078)'
334     );
335 };
336
337 subtest 'GetItemTypesCategorized test' => sub {
338     plan tests => 9;
339
340     my $avc = Koha::AuthorisedValueCategories->find('ITEMTYPECAT');
341     Koha::AuthorisedValueCategory->new({ category_name => 'ITEMTYPECAT' })->store unless $avc;
342     my $insertGroup = Koha::AuthorisedValue->new(
343         {   category         => 'ITEMTYPECAT',
344             authorised_value => 'Qwertyware',
345             lib              => 'Keyboard software',
346             lib_opac         => 'Computer stuff',
347         }
348     )->store;
349
350     ok($insertGroup, "Create group Qwertyware");
351
352     my $query = "INSERT into itemtypes (itemtype, description, searchcategory, hideinopac) values (?,?,?,?)";
353     my $insertSth = C4::Context->dbh->prepare($query);
354     $insertSth->execute('BKghjklo1', 'One type of book', '', 0);
355     $insertSth->execute('BKghjklo2', 'Another type of book', 'Qwertyware', 0);
356     $insertSth->execute('BKghjklo3', 'Yet another type of book', 'Qwertyware', 0);
357
358     # Azertyware should not exist.
359     my @itemtypes = Koha::ItemTypes->search({ searchcategory => 'Azertyware' })->as_list;
360     is( @itemtypes, 0, 'Search item types by searchcategory: Invalid category returns nothing');
361
362     @itemtypes = Koha::ItemTypes->search({ searchcategory => 'Qwertyware' })->as_list;
363     my @got = map { $_->itemtype } @itemtypes;
364     my @expected = ( 'BKghjklo2', 'BKghjklo3' );
365     is_deeply(\@got,\@expected,'Search item types by searchcategory: valid category returns itemtypes');
366
367     # add more data since GetItemTypesCategorized's search is more subtle
368     $insertGroup = Koha::AuthorisedValue->new(
369         {   category         => 'ITEMTYPECAT',
370             authorised_value => 'Veryheavybook',
371             lib              => 'Weighty literature',
372         }
373     )->store;
374
375     $insertSth->execute('BKghjklo4', 'Another hidden book', 'Veryheavybook', 1);
376
377     my $hrCat = GetItemTypesCategorized();
378     ok(exists $hrCat->{Qwertyware}, 'GetItemTypesCategorized: fully visible category exists');
379     ok($hrCat->{Veryheavybook} &&
380        $hrCat->{Veryheavybook}->{hideinopac}==1, 'GetItemTypesCategorized: non-visible category hidden' );
381
382     is( $hrCat->{Veryheavybook}->{description}, 'Weighty literature', 'A category with only lib description passes through');
383     is( $hrCat->{Qwertyware}->{description}, 'Computer stuff', 'A category with lib_opac description uses that');
384
385     $insertSth->execute('BKghjklo5', 'An hidden book', 'Qwertyware', 1);
386     $hrCat = GetItemTypesCategorized();
387     ok(exists $hrCat->{Qwertyware}, 'GetItemTypesCategorized: partially visible category exists');
388
389     my @only = ( 'BKghjklo1', 'BKghjklo2', 'BKghjklo3', 'BKghjklo4', 'BKghjklo5', 'Qwertyware', 'Veryheavybook' );
390     my @results = ();
391     foreach my $key (@only) {
392         push @results, $key if exists $hrCat->{$key};
393     }
394     @expected = ( 'BKghjklo1', 'Qwertyware', 'Veryheavybook' );
395     is_deeply(\@results,\@expected, 'GetItemTypesCategorized: grouped and ungrouped items returned as expected.');
396 };
397
398 $schema->storage->txn_rollback;