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