Bug 5304: Use branch codes from the database rather than hardcoded CPL and MPL
[koha.git] / t / db_dependent / Items.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 under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 2 of the License, or (at your option) any later
8 # version.
9 #
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with Koha; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 #
18
19 use Modern::Perl;
20
21 use MARC::Record;
22 use C4::Biblio;
23 use C4::Branch;
24 use Koha::Database;
25
26 use Test::More tests => 6;
27
28 BEGIN {
29     use_ok('C4::Items');
30 }
31
32 my $dbh = C4::Context->dbh;
33 my $branches = GetBranches;
34 my ($branch1, $branch2) = keys %$branches;
35
36 subtest 'General Add, Get and Del tests' => sub {
37
38     plan tests => 6;
39
40     # Start transaction
41     $dbh->{AutoCommit} = 0;
42     $dbh->{RaiseError} = 1;
43
44     # Create a biblio instance for testing
45     C4::Context->set_preference('marcflavour', 'MARC21');
46     my ($bibnum, $bibitemnum) = get_biblio();
47
48     # Add an item.
49     my ($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem({ homebranch => $branch1, holdingbranch => $branch1 } , $bibnum);
50     cmp_ok($item_bibnum, '==', $bibnum, "New item is linked to correct biblionumber.");
51     cmp_ok($item_bibitemnum, '==', $bibitemnum, "New item is linked to correct biblioitemnumber.");
52
53     # Get item.
54     my $getitem = GetItem($itemnumber);
55     cmp_ok($getitem->{'itemnumber'}, '==', $itemnumber, "Retrieved item has correct itemnumber.");
56     cmp_ok($getitem->{'biblioitemnumber'}, '==', $item_bibitemnum, "Retrieved item has correct biblioitemnumber.");
57
58     # Modify item; setting barcode.
59     ModItem({ barcode => '987654321' }, $bibnum, $itemnumber);
60     my $moditem = GetItem($itemnumber);
61     cmp_ok($moditem->{'barcode'}, '==', '987654321', 'Modified item barcode successfully to: '.$moditem->{'barcode'} . '.');
62
63     # Delete item.
64     DelItem({ biblionumber => $bibnum, itemnumber => $itemnumber });
65     my $getdeleted = GetItem($itemnumber);
66     is($getdeleted->{'itemnumber'}, undef, "Item deleted as expected.");
67
68     $dbh->rollback;
69 };
70
71 subtest 'GetHiddenItemnumbers tests' => sub {
72
73     plan tests => 9;
74
75     # This sub is controlled by the OpacHiddenItems system preference.
76
77     # Start transaction
78     $dbh->{AutoCommit} = 0;
79     $dbh->{RaiseError} = 1;
80
81     # Create a new biblio
82     C4::Context->set_preference('marcflavour', 'MARC21');
83     my ($biblionumber, $biblioitemnumber) = get_biblio();
84
85     # Add branches if they don't exist
86     if (not defined GetBranchDetail('CPL')) {
87         ModBranch({add => 1, branchcode => 'CPL', branchname => 'Centerville'});
88     }
89     if (not defined GetBranchDetail('MPL')) {
90         ModBranch({add => 1, branchcode => 'MPL', branchname => 'Midway'});
91     }
92
93     # Add two items
94     my ($item1_bibnum, $item1_bibitemnum, $item1_itemnumber) = AddItem(
95             { homebranch => $branch1,
96               holdingbranch => $branch1,
97               withdrawn => 1 },
98             $biblionumber
99     );
100     my ($item2_bibnum, $item2_bibitemnum, $item2_itemnumber) = AddItem(
101             { homebranch => $branch2,
102               holdingbranch => $branch2,
103               withdrawn => 0 },
104             $biblionumber
105     );
106
107     my $opachiddenitems;
108     my @itemnumbers = ($item1_itemnumber,$item2_itemnumber);
109     my @hidden;
110     my @items;
111     push @items, GetItem( $item1_itemnumber );
112     push @items, GetItem( $item2_itemnumber );
113
114     # Empty OpacHiddenItems
115     C4::Context->set_preference('OpacHiddenItems','');
116     ok( !defined( GetHiddenItemnumbers( @items ) ),
117         "Hidden items list undef if OpacHiddenItems empty");
118
119     # Blank spaces
120     C4::Context->set_preference('OpacHiddenItems','  ');
121     ok( scalar GetHiddenItemnumbers( @items ) == 0,
122         "Hidden items list empty if OpacHiddenItems only contains blanks");
123
124     # One variable / value
125     $opachiddenitems = "
126         withdrawn: [1]";
127     C4::Context->set_preference( 'OpacHiddenItems', $opachiddenitems );
128     @hidden = GetHiddenItemnumbers( @items );
129     ok( scalar @hidden == 1, "Only one hidden item");
130     is( $hidden[0], $item1_itemnumber, "withdrawn=1 is hidden");
131
132     # One variable, two values
133     $opachiddenitems = "
134         withdrawn: [1,0]";
135     C4::Context->set_preference( 'OpacHiddenItems', $opachiddenitems );
136     @hidden = GetHiddenItemnumbers( @items );
137     ok( scalar @hidden == 2, "Two items hidden");
138     is_deeply( \@hidden, \@itemnumbers, "withdrawn=1 and withdrawn=0 hidden");
139
140     # Two variables, a value each
141     $opachiddenitems = "
142         withdrawn: [1]
143         homebranch: [$branch2]
144     ";
145     C4::Context->set_preference( 'OpacHiddenItems', $opachiddenitems );
146     @hidden = GetHiddenItemnumbers( @items );
147     ok( scalar @hidden == 2, "Two items hidden");
148     is_deeply( \@hidden, \@itemnumbers, "withdrawn=1 and homebranch=MPL hidden");
149
150     # Valid OpacHiddenItems, empty list
151     @items = ();
152     @hidden = GetHiddenItemnumbers( @items );
153     ok( scalar @hidden == 0, "Empty items list, no item hidden");
154
155     $dbh->rollback;
156 };
157
158 subtest 'GetItemsInfo tests' => sub {
159
160     plan tests => 3;
161
162     # Start transaction
163     $dbh->{AutoCommit} = 0;
164     $dbh->{RaiseError} = 1;
165
166     # Add a biblio
167     my ($biblionumber, $biblioitemnumber) = get_biblio();
168     # Add an item
169     my ($item_bibnum, $item_bibitemnum, $itemnumber)
170         = AddItem({
171                 homebranch    => $branch1,
172                 holdingbranch => $branch2
173             }, $biblionumber );
174
175     my $branch = GetBranchDetail( $branch1 );
176     $branch->{ opac_info } = "homebranch OPAC info";
177     ModBranch($branch);
178
179     $branch = GetBranchDetail( $branch2 );
180     $branch->{ opac_info } = "holdingbranch OPAC info";
181     ModBranch($branch);
182
183     my @results = GetItemsInfo( $biblionumber );
184     ok( @results, 'GetItemsInfo returns results');
185     is( $results[0]->{ home_branch_opac_info }, "homebranch OPAC info",
186         'GetItemsInfo returns the correct home branch OPAC info notice' );
187     is( $results[0]->{ holding_branch_opac_info }, "holdingbranch OPAC info",
188         'GetItemsInfo returns the correct holding branch OPAC info notice' );
189
190     $dbh->rollback;
191 };
192
193 subtest q{Test Koha::Database->schema()->resultset('Item')->itemtype()} => sub {
194
195     plan tests => 2;
196
197     # Start transaction
198     $dbh->{AutoCommit} = 0;
199     $dbh->{RaiseError} = 1;
200
201     my $schema = Koha::Database->new()->schema();
202
203     my $biblio =
204     $schema->resultset('Biblio')->create(
205         {
206             title       => "Test title",
207             biblioitems => [
208                 {
209                     itemtype => 'BIB_LEVEL',
210                     items    => [ { itype => "ITEM_LEVEL" } ]
211                 }
212             ]
213         }
214     );
215
216     my $biblioitem = $biblio->biblioitem();
217     my ( $item ) = $biblioitem->items();
218
219     C4::Context->set_preference( 'item-level_itypes', 0 );
220     ok( $item->effective_itemtype() eq 'BIB_LEVEL', '$item->itemtype() returns biblioitem.itemtype when item-level_itypes is disabled' );
221
222     C4::Context->set_preference( 'item-level_itypes', 1 );
223     ok( $item->effective_itemtype() eq 'ITEM_LEVEL', '$item->itemtype() returns items.itype when item-level_itypes is enabled' );
224
225     $dbh->rollback;
226 };
227
228 subtest 'SearchItems test' => sub {
229     plan tests => 10;
230
231     # Start transaction
232     $dbh->{AutoCommit} = 0;
233     $dbh->{RaiseError} = 1;
234
235     C4::Context->set_preference('marcflavour', 'MARC21');
236     my ($biblionumber) = get_biblio();
237
238     # Add branches if they don't exist
239     if (not defined GetBranchDetail('CPL')) {
240         ModBranch({add => 1, branchcode => 'CPL', branchname => 'Centerville'});
241     }
242     if (not defined GetBranchDetail('MPL')) {
243         ModBranch({add => 1, branchcode => 'MPL', branchname => 'Midway'});
244     }
245
246     my (undef, $initial_items_count) = SearchItems(undef, {rows => 1});
247
248     # Add two items
249     my (undef, undef, $item1_itemnumber) = AddItem({
250         homebranch => 'CPL',
251         holdingbranch => 'CPL',
252     }, $biblionumber);
253     my (undef, undef, $item2_itemnumber) = AddItem({
254         homebranch => 'MPL',
255         holdingbranch => 'MPL',
256     }, $biblionumber);
257
258     my ($items, $total_results);
259
260     ($items, $total_results) = SearchItems();
261     is($total_results, $initial_items_count + 2, "Created 2 new items");
262     is(scalar @$items, $total_results, "SearchItems() returns all items");
263
264     ($items, $total_results) = SearchItems(undef, {rows => 1});
265     is($total_results, $initial_items_count + 2);
266     is(scalar @$items, 1, "SearchItems(undef, {rows => 1}) returns only 1 item");
267
268     # Search all items where homebranch = 'CPL'
269     my $filter = {
270         field => 'homebranch',
271         query => 'CPL',
272         operator => '=',
273     };
274     ($items, $total_results) = SearchItems($filter);
275     ok($total_results > 0, "There is at least one CPL item");
276     my $all_items_are_CPL = 1;
277     foreach my $item (@$items) {
278         if ($item->{homebranch} ne 'CPL') {
279             $all_items_are_CPL = 0;
280             last;
281         }
282     }
283     ok($all_items_are_CPL, "All items returned by SearchItems are from CPL");
284
285     # Search all items where homebranch != 'CPL'
286     $filter = {
287         field => 'homebranch',
288         query => 'CPL',
289         operator => '!=',
290     };
291     ($items, $total_results) = SearchItems($filter);
292     ok($total_results > 0, "There is at least one non-CPL item");
293     my $all_items_are_not_CPL = 1;
294     foreach my $item (@$items) {
295         if ($item->{homebranch} eq 'CPL') {
296             $all_items_are_not_CPL = 0;
297             last;
298         }
299     }
300     ok($all_items_are_not_CPL, "All items returned by SearchItems are not from CPL");
301
302     # Search all items where biblio title (245$a) is like 'Silence in the %'
303     $filter = {
304         field => 'marc:245$a',
305         query => 'Silence in the %',
306         operator => 'like',
307     };
308     ($items, $total_results) = SearchItems($filter);
309     ok($total_results >= 2, "There is at least 2 items with a biblio title like 'Silence in the %'");
310
311     # Search all items where biblio title is 'Silence in the library'
312     # and homebranch is 'CPL'
313     $filter = {
314         conjunction => 'AND',
315         filters => [
316             {
317                 field => 'marc:245$a',
318                 query => 'Silence in the %',
319                 operator => 'like',
320             },
321             {
322                 field => 'homebranch',
323                 query => 'CPL',
324                 operator => '=',
325             },
326         ],
327     };
328     ($items, $total_results) = SearchItems($filter);
329     my $found = 0;
330     foreach my $item (@$items) {
331         if ($item->{itemnumber} == $item1_itemnumber) {
332             $found = 1;
333             last;
334         }
335     }
336     ok($found, "item1 found");
337
338     $dbh->rollback;
339 };
340
341 # Helper method to set up a Biblio.
342 sub get_biblio {
343     my $bib = MARC::Record->new();
344     $bib->append_fields(
345         MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
346         MARC::Field->new('245', ' ', ' ', a => 'Silence in the library'),
347     );
348     my ($bibnum, $bibitemnum) = AddBiblio($bib, '');
349     return ($bibnum, $bibitemnum);
350 }