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