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