smart-rules.pl - tighten regexp, Debug for warn statements, readable layout.
[koha.git] / t / lib / KohaTest.pm
1 package KohaTest;
2 use base qw(Test::Class);
3
4 use Test::More;
5 use Data::Dumper;
6
7 eval "use Test::Class";
8 plan skip_all => "Test::Class required for performing database tests" if $@;
9 # Or, maybe I should just die there.
10
11 use C4::Biblio;
12 use C4::Bookfund;
13 use C4::Bookseller;
14 use C4::Context;
15 use C4::Items;
16 use C4::Members;
17 use C4::Search;
18
19 # Since this is an abstract base class, this prevents these tests from
20 # being run directly unless we're testing a subclass. It just makes
21 # things faster.
22 __PACKAGE__->SKIP_CLASS( 1 );
23
24
25 =head2 startup methods
26
27 these are run once, at the beginning of the whole test suite
28
29 =cut
30
31 sub startup_15_truncate_tables : Test( startup => 1 ) {
32     my $self = shift;
33     
34 #     my @truncate_tables = qw( accountlines 
35 #                               accountoffsets              
36 #                               action_logs                 
37 #                               alert                       
38 #                               aqbasket                    
39 #                               aqbookfund                  
40 #                               aqbooksellers               
41 #                               aqbudget                    
42 #                               aqorderbreakdown            
43 #                               aqorderdelivery             
44 #                               aqorders                    
45 #                               auth_header                 
46 #                               auth_subfield_structure     
47 #                               auth_tag_structure          
48 #                               auth_types                  
49 #                               authorised_values           
50 #                               biblio                      
51 #                               biblio_framework            
52 #                               biblioitems                 
53 #                               borrowers                   
54 #                               branchcategories            
55 #                               branches                    
56 #                               branchrelations             
57 #                               branchtransfers             
58 #                               browser                     
59 #                               categories                  
60 #                               categorytable               
61 #                               cities                      
62 #                               class_sort_rules            
63 #                               class_sources               
64 #                               currency                    
65 #                               deletedbiblio               
66 #                               deletedbiblioitems          
67 #                               deletedborrowers            
68 #                               deleteditems                
69 #                               ethnicity                   
70 #                               import_batches              
71 #                               import_biblios              
72 #                               import_items                
73 #                               import_record_matches       
74 #                               import_records              
75 #                               issues                      
76 #                               issuingrules                
77 #                               items                       
78 #                               itemtypes                   
79 #                               labels                      
80 #                               labels_conf                 
81 #                               labels_profile              
82 #                               labels_templates            
83 #                               language_descriptions       
84 #                               language_rfc4646_to_iso639  
85 #                               language_script_bidi        
86 #                               language_script_mapping     
87 #                               language_subtag_registry    
88 #                               letter                      
89 #                               marc_matchers               
90 #                               marc_subfield_structure     
91 #                               marc_tag_structure          
92 #                               matchchecks                 
93 #                               matcher_matchpoints         
94 #                               matchpoint_component_norms  
95 #                               matchpoint_components       
96 #                               matchpoints                 
97 #                               mediatypetable              
98 #                               notifys                     
99 #                               nozebra                     
100 #                               old_issues                  
101 #                               old_reserves                
102 #                               opac_news                   
103 #                               overduerules                
104 #                               patroncards                 
105 #                               patronimage                 
106 #                               printers                    
107 #                               printers_profile            
108 #                               repeatable_holidays         
109 #                               reports_dictionary          
110 #                               reserveconstraints          
111 #                               reserves                    
112 #                               reviews                     
113 #                               roadtype                    
114 #                               saved_reports               
115 #                               saved_sql                   
116 #                               serial                      
117 #                               serialitems                 
118 #                               services_throttle           
119 #                               sessions                    
120 #                               special_holidays            
121 #                               statistics                  
122 #                               stopwords                   
123 #                               subcategorytable            
124 #                               subscription                
125 #                               subscriptionhistory         
126 #                               subscriptionroutinglist     
127 #                               suggestions                 
128 #                               systempreferences           
129 #                               tags                        
130 #                               userflags                   
131 #                               virtualshelfcontents        
132 #                               virtualshelves              
133 #                               z3950servers                
134 #                               zebraqueue                  
135 #                         );
136
137     my @truncate_tables = qw( accountlines 
138                               accountoffsets              
139                               alert                       
140                               aqbasket                    
141                               aqbooksellers               
142                               aqorderbreakdown            
143                               aqorderdelivery             
144                               aqorders                    
145                               auth_header                 
146                               branchcategories            
147                               branchrelations             
148                               branchtransfers             
149                               browser                     
150                               categorytable               
151                               cities                      
152                               deletedbiblio               
153                               deletedbiblioitems          
154                               deletedborrowers            
155                               deleteditems                
156                               ethnicity                   
157                               import_items                
158                               import_record_matches       
159                               issues                      
160                               issuingrules                
161                               items                       
162                               labels                      
163                               labels_profile              
164                               matchchecks                 
165                               mediatypetable              
166                               notifys                     
167                               nozebra                     
168                               old_issues                  
169                               old_reserves                
170                               overduerules                
171                               patroncards                 
172                               patronimage                 
173                               printers                    
174                               printers_profile            
175                               reports_dictionary          
176                               reserveconstraints          
177                               reserves                    
178                               reviews                     
179                               roadtype                    
180                               saved_reports               
181                               saved_sql                   
182                               serial                      
183                               serialitems                 
184                               services_throttle           
185                               special_holidays            
186                               statistics                  
187                               subcategorytable            
188                               subscription                
189                               subscriptionhistory         
190                               subscriptionroutinglist     
191                               suggestions                 
192                               tags                        
193                               virtualshelfcontents        
194                         );
195     
196     my $failed_to_truncate = 0;
197     foreach my $table ( @truncate_tables ) {
198         my $dbh = C4::Context->dbh();
199         $dbh->do( "truncate $table" )
200           or $failed_to_truncate = 1;
201     }
202     is( $failed_to_truncate, 0, 'truncated tables' );
203     
204 }
205
206 =head2 startup_20_add_bookseller
207
208 we need a bookseller for many of the tests, so let's insert one. Feel
209 free to use this one, or insert your own.
210
211 =cut
212
213 sub startup_20_add_bookseller : Test(startup => 1) {
214     my $self = shift;
215
216     my $booksellerinfo = { name => 'bookseller ' . $self->random_string(),
217                       };
218
219     my $id = AddBookseller( $booksellerinfo );
220     ok( $id, "created bookseller: $id" );
221     $self->{'booksellerid'} = $id;
222     
223     return;
224 }
225
226 =head2 startup_22_add_bookfund
227
228 we need a bookfund for many of the tests. This currently uses one that
229 is in the skeleton database.  free to use this one, or insert your
230 own.
231
232 =cut
233
234 sub startup_22_add_bookfund : Test(startup => 2) {
235     my $self = shift;
236
237     my $bookfundid = 'GEN';
238     my $bookfund = GetBookFund( $bookfundid, undef );
239     # diag( Data::Dumper->Dump( [ $bookfund ], qw( bookfund  ) ) );
240     is( $bookfund->{'bookfundid'},   $bookfundid,      "found bookfund: '$bookfundid'" );
241     is( $bookfund->{'bookfundname'}, 'General Stacks', "found bookfund: '$bookfundid'" );
242     
243     $self->{'bookfundid'} = $bookfundid;
244     return;
245 }
246
247 =head2 startup_24_add_member
248
249 Add a patron/member for the tests to use
250
251 =cut
252
253 sub startup_24_add_member : Test(startup => 1) {
254     my $self = shift;
255
256     my $memberinfo = { surname      => 'surname '  . $self->random_string(),
257                        firstname    => 'firstname' . $self->random_string(),
258                        address      => 'address'   . $self->random_string(),
259                        city         => 'city'      . $self->random_string(),
260                        branchcode   => 'CPL', # CPL => Centerville
261                        categorycode => 'PT',  # PT  => PaTron
262                   };
263
264     my $id = AddMember( %$memberinfo );
265     ok( $id, "created member: $id" );
266     $self->{'memberid'} = $id;
267     
268     return;
269 }
270
271 =head2 setup methods
272
273 setup methods are run before every test method
274
275 =cut
276
277 =head2 teardown methods
278
279 teardown methods are many time, once at the end of each test method.
280
281 =cut
282
283 =head2 shutdown methods
284
285 shutdown methods are run once, at the end of the test suite
286
287 =cut
288
289 =head2 utility methods
290
291 These are not test methods, but they're handy
292
293 =cut
294
295 =head3 random_string
296
297 Nice for generating names and such. It's not actually random, more
298 like arbitrary.
299
300 =cut
301
302 sub random_string {
303     my $self = shift;
304
305     my $wordsize = 6;  # how many letters in your string?
306
307     # leave out these characters: "oOlL10". They're too confusing.
308     my @alphabet = ( 'a'..'k','m','n','p'..'z', 'A'..'K','M','N','P'..'Z', 2..9 );
309
310     my $randomstring;
311     foreach ( 0..$wordsize ) {
312         $randomstring .= $alphabet[ rand( scalar( @alphabet ) ) ];
313     }
314     return $randomstring;
315     
316 }
317
318 =head3 add_biblios
319
320   $self->add_biblios( count     => 10,
321                       add_items => 1, );
322
323   named parameters:
324      count: number of biblios to add
325      add_items: should you add items for each one?
326
327   returns:
328     I don't know yet.
329
330   side effects:
331     adds the biblionumbers to the $self->{'biblios'} listref
332
333   Notes:
334     Should I allow you to pass in biblio information, like title?
335     Since this method is in the KohaTest class, all tests in it will be ignored, unless you call this from your own namespace.
336     This runs 10 tests, plus 4 for each "count", plus 3 more for each item added.
337
338 =cut
339
340 sub add_biblios {
341     my $self = shift;
342     my %param = @_;
343
344     $param{'count'}     = 1 unless defined( $param{'count'} );
345     $param{'add_items'} = 0 unless defined( $param{'add_items'} );
346
347     foreach my $counter ( 1..$param{'count'} ) {
348         my $marcrecord  = MARC::Record->new();
349         isa_ok( $marcrecord, 'MARC::Record' );
350         my $appendedfieldscount = $marcrecord->append_fields( MARC::Field->new( '100', '1', '0',
351                                                                                 a => 'Twain, Mark',
352                                                                                 d => "1835-1910." ),
353                                                               MARC::Field->new( '245', '1', '4',
354                                                                                 a => sprintf( 'The Adventures of Huckleberry Finn Test %s', $counter ),
355                                                                                 c => "Mark Twain ; illustrated by E.W. Kemble." )
356                                                          );
357         is( $appendedfieldscount, 2, 'added 2 fields' );
358         
359         my $frameworkcode = ''; # XXX I'd like to put something reasonable here.
360         my ( $biblionumber, $biblioitemnumber ) = AddBiblio( $marcrecord, $frameworkcode );
361         ok( $biblionumber, "the biblionumber is $biblionumber" );
362         ok( $biblioitemnumber, "the biblioitemnumber is $biblioitemnumber" );
363         if ( $param{'add_items'} ) {
364             # my @iteminfo = AddItem( {}, $biblionumber );
365             my @iteminfo = AddItemFromMarc( $marcrecord, $biblionumber );
366             is( $iteminfo[0], $biblionumber,     "biblionumber is $biblionumber" );
367             is( $iteminfo[1], $biblioitemnumber, "biblioitemnumber is $biblioitemnumber" );
368             ok( $iteminfo[2], "itemnumber is $iteminfo[2]" );
369         }
370         push @{$self->{'biblios'}}, $biblionumber;
371     }
372     
373     my $query = 'Finn Test';
374
375     # XXX we're going to repeatedly try to fetch the marc records that
376     # we inserted above. It may take a while before they all show
377     # up. why?
378     my $tries = 30;
379     DELAY: foreach my $trial ( 1..$tries ) {
380         diag "waiting for zebra indexing. Trial: $trial of $tries";
381         my ( $error, $results ) = SimpleSearch( $query );
382         if ( $param{'count'} <= scalar( @$results ) ) {
383             ok( $tries, "found all $param{'count'} titles after $trial tries" );
384             last DELAY;
385         }
386         sleep( 3 );
387     } continue {
388         if ( $trial == $tries ) {
389             fail( "we never found all $param{'count'} titles even after $tries tries." );
390         }
391     }
392
393     
394 }
395
396 1;