Bug 10386: improvements to VirtualShelves.t
[koha.git] / t / db_dependent / VirtualShelves.t
1 #!/usr/bin/perl
2
3 # This file is a test script for C4::VirtualShelves.pm
4 # Author : Antoine Farnault, antoine@koha-fr.org
5 # Larger modifications by Jonathan Druart and Marcel de Rooy
6
7 use Modern::Perl;
8 use Test::More tests => 81;
9 use MARC::Record;
10
11 use C4::Biblio qw( AddBiblio DelBiblio );
12 use C4::Context;
13
14 # Getting some borrowers from database.
15 my $dbh = C4::Context->dbh;
16 my $query = q{SELECT borrowernumber FROM borrowers LIMIT 10};
17 my $borr_ref=$dbh->selectall_arrayref($query);
18 if(@$borr_ref==0) { #no borrowers? should not occur of course
19     $borr_ref->[0][0]=undef;
20         #but even then, we can run this robust test :)
21 }
22 my @borrowers;
23 foreach(1..10) {
24     my $t= $_> @$borr_ref ? int(rand()*@$borr_ref): $_-1; #repeat if not enough
25     push @borrowers, $borr_ref->[$t][0];
26 }
27
28 # Creating some biblios
29 my @biblionumbers;
30 foreach(0..9) {
31     my ($biblionumber)= AddBiblio(MARC::Record->new, '');
32         #item number ignored
33     push @biblionumbers, $biblionumber;
34 }
35
36 #----------------------------------------------------------------------#
37 #
38 #           TESTS START HERE
39 #
40 #----------------------------------------------------------------------#
41
42 use_ok('C4::VirtualShelves');
43
44 #-----------------------TEST AddShelf function------------------------#
45 # usage : $shelfnumber = &AddShelf( $shelfname, $owner, $category);
46
47 # creating shelves (could be <10 when names are not unique)
48 my @shelves;
49 for(my $i=0; $i<10;$i++) {
50     my $name= randomname();
51     my $catg= int(rand(2))+1;
52     my $ShelfNumber= AddShelf(
53         {
54             shelfname => $name,
55             category  => $catg,
56         },
57         $borrowers[$i]);
58
59     if($ShelfNumber>-1) {
60         ok($ShelfNumber > -1, "created shelf");   # Shelf creation successful;
61     }
62     else {
63         my $t= C4::VirtualShelves::_CheckShelfName(
64             $name, $catg, $borrowers[$i], 0);
65         ok($t==0, "Name clash expected on shelf creation");
66     }
67     push @shelves, {
68         number => $ShelfNumber,
69         name   => $name,
70         catg   => $catg,
71         owner  => $borrowers[$i],
72     }; #also push the errors
73 }
74
75 # try to create shelves with duplicate names
76 for(my $i=0;$i<10;$i++){
77     if($shelves[$i]->{number}<0) {
78         ok(1, 'skip duplicate test for earlier name clash');
79         next;
80     }
81     my @shlf=GetShelf($shelves[$i]->{number}); #number, name, owner, catg, ...
82
83     # A shelf name is not per se unique!
84     if( $shlf[3]==2 ) { #public list: try to create with same name
85         my $badNumShelf= AddShelf( {
86             shelfname=> $shelves[$i]->{name},
87             category => 2
88         }, $borrowers[$i]);
89         ok(-1==$badNumShelf, 'do not create public lists with duplicate names');
90             #AddShelf returns -1 if name already exist.
91         DelShelf($badNumShelf) if $badNumShelf>-1; #delete if went wrong..
92     }
93     else { #private list, try to add another one for SAME user (owner)
94         my $badNumShelf= defined($shlf[2])? AddShelf(
95             {
96                 shelfname=> $shelves[$i]->{name},
97                 category => 1,
98             },
99             $shlf[2]): -1;
100         ok(-1==$badNumShelf, 'do not create private lists with duplicate name for same user');
101         DelShelf($badNumShelf) if $badNumShelf>-1; #delete if went wrong..
102     }
103 }
104
105 #-----------TEST AddToShelf & GetShelfContents &  DelFromShelf functions--------------#
106 # usage : &AddToShelf($biblionumber, $shelfnumber);
107 # usage : $biblist = &GetShelfContents($shelfnumber);
108 # usage : $biblist = GetShelfContents($shelfnumber);
109
110 my %used = ();
111 for(my $i=0; $i<10;$i++){
112     my $bib = $biblionumbers[int(rand(9))];
113     my $shelfnumber = $shelves[int(rand(9))]->{number};
114     if($shelfnumber<0) {
115         ok(1, 'skip add to list-test for shelf -1');
116         ok(1, 'skip counting list entries for shelf -1');
117         next;
118     }
119
120     my $key = "$bib\t$shelfnumber";
121     my $should_fail = exists($used{$key}) ? 1 : 0;
122     #FIXME We assume here that we have permission to add..
123     #The different permissions could be tested too.
124
125     my ($biblistBefore,$countbefore) = GetShelfContents($shelfnumber);
126     my $status = AddToShelf($bib,$shelfnumber,$borrowers[$i]);
127     my ($biblistAfter,$countafter) = GetShelfContents($shelfnumber);
128
129     if ($should_fail) {
130         ok(!defined($status), 'failed to add to list when we should');
131     } else {
132         ok(defined($status), 'added to list when we should');
133     }
134
135     if (defined $status) {
136         ok($countbefore == $countafter - 1, 'added bib to list');  # the bib has been successfuly added.
137     } else {
138         ok($countbefore == $countafter, 'did not add duplicate bib to list');
139     }
140
141     $used{$key}++;
142 }
143
144 #-----------------------TEST ModShelf & GetShelf functions------------------------#
145 # usage : ModShelf($shelfnumber, $shelfname, $owner, $category )
146 # usage : (shelfnumber,shelfname,owner,category) = GetShelf($shelfnumber);
147
148 for(my $i=0; $i<10;$i++){
149     my $rand = int(rand(9));
150     my $numA = $shelves[$rand]->{number};
151     if($numA<0) {
152         ok(1, 'Skip ModShelf test for shelf -1');
153         ok(1, 'Skip ModShelf test for shelf -1');
154         ok(1, 'Skip ModShelf test for shelf -1');
155         next;
156     }
157     my $newname= randomname();
158     my $shelf = {
159         shelfname => $newname,
160         category =>  3-$shelves[$rand]->{catg}, # tric: 1->2 and 2->1
161     };
162     #check name change (with category change)
163     if(C4::VirtualShelves::_CheckShelfName($newname,$shelf->{category},
164             $shelves[$rand]->{owner}, $numA)) {
165         ModShelf($numA,$shelf);
166         my ($numB,$nameB,$ownerB,$categoryB) = GetShelf($numA);
167         ok($numA == $numB, 'modified shelf');
168         ok($shelf->{shelfname} eq $nameB,     '... and name change took');
169         ok($shelf->{category}  eq $categoryB, '... and category change took');
170     }
171     else {
172         ok(1, "No ModShelf for $newname") for 1..3;
173     }
174 }
175
176 #-----------------------TEST DelShelf & DelFromShelf functions------------------------#
177 # usage : ($status) = &DelShelf($shelfnumber);
178
179 for(my $i=0; $i<10;$i++){
180     my $shelfnumber = $shelves[$i]->{number};
181     if($shelfnumber<0) {
182         ok(1, 'Skip DelShelf for shelf -1');
183         next;
184     }
185     my $status = DelShelf($shelfnumber);
186     ok(1 == $status, "deleted shelf $shelfnumber and its contents");
187 }
188
189 #----------------------- CLEANUP ----------------------------------------------#
190
191 DelBiblio($_) for @biblionumbers;
192
193 #----------------------- SOME SUBS --------------------------------------------#
194
195 sub randomname {
196     my $rv='';
197     for(0..19) {
198         $rv.= ('a'..'z','A'..'Z',0..9) [int(rand()*62)];
199     }
200     return $rv;
201 }