Merge pull request #42 from solgenomics/topic/duplicate_image_warning
[cxgn-corelibs.git] / t / CXGN / Metadata / metadbdata.t
blobda9c1dc24c067eaec4e21b1a73f6c91e09bcd8d7
1 #!/usr/bin/perl
3 =head1 NAME
5 metadbdata.t
6 A piece of code to test the CXGN::Metadata::Metadbdata module
8 =cut
10 =head1 SYNOPSIS
12 perl metadata.t
14 Note: To run the complete test the database connection should be
15 done as postgres user
16 (web_usr have not privileges to insert new data into the sed tables)
18 this test need some environment variables:
20 export METADATA_TEST_METALOADER='metaloader user'
21 export METADATA_TEST_DBDSN='database dsn as:
22 dbi:DriverName:database=database_name;host=hostname;port=port'
24 example:
25 export METADATA_TEST_DBDSN='dbi:Pg:database=sandbox;host=localhost;'
27 export METADATA_TEST_DBUSER='database user with insert permissions'
28 export METADATA_TEST_DBPASS='database password'
30 =head1 DESCRIPTION
32 This script check 57 variables to test the right operation of the CXGN::Metadata::Metadbdata module:
34 + test 1 and 2: Test for module use
35 + test from 3 to 11: Test the accessors (set and get) in an empty object.
36 + test 12: Test the create_person_id_by_username function that set the create_person_id value using a username.
37 + test 13: Test the store function without previous metadata_id (a new metadata for a new Sgn Expression Data).
38 + test 14: Test the store function with a previous metadata_id (modify Sgn Expression Data, so it create a new metadata
39 with a old metadata_id as previous metadata, in this case to obsolete a SED value)
40 + test 15: get obsolete data from a metadata object.
41 + test from 16 to 42: check the data obtained from the trace_history function
42 + test 43 and 45: check the find_or_store function
43 + test 46: check the exists_database_columns function
44 + test from 47 to 48: check the exists_metadata for different metadata_types
45 + test from 49 to 52: check the enforce functions (enforce_insert and enforce_update).
47 =cut
49 =head1 AUTHORS
51 Aureliano Bombarely Gomez
52 (ab782@cornell.edu)
54 =cut
57 use strict;
58 use warnings;
60 use Data::Dumper;
61 use Test::More; # use qw | no_plan | while developing the tests
63 use CXGN::DB::Connection;
65 ## The tests still need search_path
67 my @schema_list = ('metadata', 'public');
68 my $schema_list = join(',', @schema_list);
69 my $set_path = "SET search_path TO $schema_list";
71 ## First check env. variables and connection
73 BEGIN {
75 ## Env. variables have been changed to use biosource specific ones
77 my @env_variables = qw/METADATA_TEST_METALOADER METADATA_TEST_DBDSN METADATA_TEST_DBUSER METADATA_TEST_DBPASS/;
79 for my $env (@env_variables) {
80 unless (defined $ENV{$env}) {
81 plan skip_all => "Environment variable $env not set, aborting";
85 eval {
86 CXGN::DB::Connection->new(
87 $ENV{METADATA_TEST_DBDSN},
88 $ENV{METADATA_TEST_DBUSER},
89 $ENV{METADATA_TEST_DBPASS},
90 {on_connect_do => $set_path}
91 );
94 if ($@ =~ m/DBI connect/) {
96 plan skip_all => "Could not connect to database";
99 plan tests => 53;
102 BEGIN {
103 use_ok('CXGN::Metadata::Schema'); ## TEST1
104 use_ok('CXGN::Metadata::Metadbdata'); ## TEST2
108 #if we cannot load the CXGN::Metadata::Schema module, no point in continuing
109 CXGN::Metadata::Schema->can('connect')
110 or BAIL_OUT('could not load the CXGN::Metadata::Schema module');
112 ## Prespecified variable
114 my $metadata_creation_user = $ENV{METADATA_TEST_METALOADER};
116 ## The biosource schema contain all the metadata classes so don't need to create another Metadata schema
117 ## CXGN::DB::DBICFactory is obsolete, it has been replaced by CXGN::Metadata::Schema
119 my $schema = CXGN::Metadata::Schema->connect( $ENV{METADATA_TEST_DBDSN},
120 $ENV{METADATA_TEST_DBUSER},
121 $ENV{METADATA_TEST_DBPASS},
122 {on_connect_do => $set_path});
124 $schema->txn_begin();
128 ## It will create some predefined times to use by the script
130 my $dbh = $schema->storage()
131 ->dbh();
133 my ($past) = $dbh->selectrow_array("SELECT now() + '-10 year'");
134 my ($present) = $dbh->selectrow_array("SELECT now()");
135 my ($future) = $dbh->selectrow_array("SELECT now() + '10 year'");
136 my ($far_future) = $dbh->selectrow_array("SELECT now() + '1000 year'");
139 ## FIRST TEST BLOCK (Test from 3 to 11)
140 ## This is the first group of tests, to check if an empty object can store and after can return the data
141 ## Create a new empty object;
143 my $metadata = CXGN::Metadata::Metadbdata->new($schema, undef);
145 ## Load of the eight different parameters for an empty object using a hash with keys=root name for tha function and
146 ## values=value to test
148 my %test_values_for_empty_object=( metadata_id => 1,
149 create_date => 'now',
150 create_person_id => 1,
151 modified_date => 'now',
152 modification_note => 'test for modification note',
153 previous_metadata_id => 0,
154 obsolete => 1,
155 obsolete_note => 'It is obsolete because it is a test',
156 permission_id => 1
159 ## Load the data in the empty object
160 my @function_keys = sort keys %test_values_for_empty_object;
161 foreach my $rootfunction (@function_keys) {
162 my $setfunction = 'set_'.$rootfunction;
163 $metadata->$setfunction($test_values_for_empty_object{$rootfunction});
165 ## Get the data from the object and store in two hashes. The first %getdata with keys=root_function_name and
166 ## value=value_get_from_object and the second, %testname with keys=root_function_name and values=name for the test.
168 my (%getdata, %testnames);
169 foreach my $rootfunction (@function_keys) {
170 my $getfunction = 'get_'.$rootfunction;
171 my $data = $metadata->$getfunction();
172 $getdata{$rootfunction} = $data;
173 my $testname = $rootfunction.' test';
174 $testnames{$rootfunction} = $testname;
177 ## And now run the test for each function and value
179 foreach my $rootfunction (@function_keys) {
180 is($getdata{$rootfunction}, $test_values_for_empty_object{$rootfunction}, $testnames{$rootfunction})
181 or diag "Looks like this failed.";
184 ## SECOND TEST BLOCK
185 ## This block test the store function in two ways, as store a new metadata and modifing a data (it create a new one too).
186 ## It was runned as eval { }, because in the end of the test we need restore the database data (and if die... )
187 ## now we are going to store, but before could be a good idea get the last_id to set the seq after all the process.
189 ## my %last_ids = $schema->get_last_id();
190 my %nextvals = $schema->get_nextval();
192 my $last_metadata_id = $nextvals{'md_metadata'};
194 eval {
196 ## Create a new empty object with object_creation_user argument
198 my $metadata_s = CXGN::Metadata::Metadbdata->new($schema, $metadata_creation_user);
200 ## Other option is use $metadata_s->set_create_person_id_by_username($creation_user_name);
201 ## The module check if exists the sp_person_id in the sgn_people.sp_person table
202 ## Use the same to test the get_create_person_id_by_username
203 ## Tests from 12 to 14
205 is ($metadata_s->get_create_person_id_by_username(), undef, 'undefined create_person_id_by_username before store test')
206 or diag "Looks like this failed.";
207 my $stored_metadata = $metadata_s->store(); ## During the store the create_person_id should be set with the value by default
208 is ($stored_metadata->get_create_person_id_by_username(), $metadata_creation_user, 'create_person_id_by_username test')
209 or diag "Looks like this failed.";
210 my $store_metadata_id = $stored_metadata->get_metadata_id();
211 my $expected_metadata_id = $last_metadata_id+1;
212 is ($store_metadata_id, $expected_metadata_id, 'store an object without metadata_id test')
213 or diag "Looks like this failed.";
215 ## Now we are going to modify a metadata. First, we are going to obsolete the data.
217 $stored_metadata->set_modified_date($future);
219 ## We do not set the modification_person_by_username to see if it get the object_creation_user by default.
220 ## An alternative is use $stored_metadata->set_modified_person_id_by_username($creation_user_name);
221 ## Test 15 and 16
223 $stored_metadata->set_modification_note('set_data');
224 my $new_stored_metadata = $stored_metadata->store(); ## Now it should create a new metadata id
225 my $new_expected_metadata_id = $last_metadata_id+2;
226 my $new_store_metadata_id = $new_stored_metadata->get_metadata_id();
227 is ($new_store_metadata_id, $new_expected_metadata_id, 'store an object with metadata_id test ')
228 or diag "Looks like this failed.";
229 is ($stored_metadata->get_obsolete(), 0, 'get obsolete from a store an object with metadata_id test')
230 or diag "Look like this failed";
232 ## We are going to mdify another time the data ans store it to see if the store function works propierly for more than one element
233 ## We take the new_stored_metadata, and do the changes over this metadata (The last got from the db).
234 ## Test 17 and 18
236 $new_stored_metadata->set_metadata_by_rows({ modified_date => $far_future, modification_note => 'set_other_data'});
237 my $newest_stored_metadata = $new_stored_metadata->store();
238 my $newest_expected_metadata_id = $last_metadata_id+3;
239 my $newest_stored_metadata_id = $newest_stored_metadata->get_metadata_id();
240 my $newest_stored_modified_date = $newest_stored_metadata->get_modified_date();
241 my $newest_stored_modification_note = $newest_stored_metadata->get_modification_note();
242 my $modification_data_combined = $newest_stored_modified_date." AND ".$newest_stored_modification_note;
243 is ($newest_stored_metadata_id, $newest_expected_metadata_id, 'store function over the object obtained from store function')
244 or diag "Looks like this failed.";
245 is ($modification_data_combined, "$far_future AND set_other_data", 'set_metadata_by_rows and store functions')
246 or diag "Looks like this failed.";
248 ## Finally we are going to try trace the history function (get use the last metadata_id)
250 my @history_metadata = $stored_metadata->trace_history($newest_stored_metadata_id);
252 ## According the data that we are insert this should have two entries:
253 ## Test 19
255 my $history_entries_number = scalar(@history_metadata);
256 is ($history_entries_number, 3, 'trace_history number of entries test')
257 or diag "Look like this failed";
259 my $third_metadata_obj = $history_metadata[0];
260 my $second_metadata_obj = $history_metadata[1];
261 my $first_metadata_obj = $history_metadata[2];
262 my %third_metadata_by_col = $third_metadata_obj->get_metadata_by_rows();
263 my %second_metadata_by_col = $second_metadata_obj->get_metadata_by_rows();
264 my %first_metadata_by_col = $first_metadata_obj->get_metadata_by_rows();
266 ## Define the values expected for the three elements of the trace processing from first (oldest) to third (newest).
268 my $general_create_date = $first_metadata_obj->get_object_creation_date();
269 my $general_create_person_id = $first_metadata_obj->get_create_person_id();
271 my $query_for_person_id = "SELECT sp_person_id FROM sgn_people.sp_person WHERE username=?";
272 my $sth_p=$schema->storage->dbh->prepare($query_for_person_id);
273 $sth_p->execute($metadata_creation_user);
274 my ($sp_person_id_for_creation_user) = $sth_p->fetchrow_array();
276 my %third_expected_metadata = ( metadata_id => $last_metadata_id+3,
277 create_date => $general_create_date,
278 create_person_id => $general_create_person_id,
279 modified_date => $far_future,
280 modified_person_id => $sp_person_id_for_creation_user,
281 modification_note => 'set_other_data',
282 obsolete => 0,
283 obsolete_note => 'undefined',
285 my $second_expected_obsolete_note = "New metadata was added (with metadata_id = ";
286 $second_expected_obsolete_note .= $last_metadata_id+3;
287 $second_expected_obsolete_note .= ")";
288 my %second_expected_metadata = ( metadata_id => $last_metadata_id+2,
289 create_date => $general_create_date,
290 create_person_id => $general_create_person_id,
291 modified_date => $future,
292 modified_person_id => $sp_person_id_for_creation_user,
293 modification_note => 'set_data',
294 obsolete => 0,
295 obsolete_note => 'undefined',
297 my $first_expected_obsolete_note = "New metadata was added (with metadata_id = ";
298 $first_expected_obsolete_note .= $last_metadata_id+2;
299 $first_expected_obsolete_note .= ")";
300 my %first_expected_metadata = ( metadata_id => $last_metadata_id+1,
301 create_date => $general_create_date,
302 create_person_id => $general_create_person_id,
303 modified_date => 'undefined',
304 modified_person_id => 'undefined',
305 modification_note => 'undefined',
306 obsolete => 0,
307 obsolete_note => 'undefined',
310 ## Now test for each element the each values for each column
311 ## Test from 20 to 43
313 my @columns = keys %first_expected_metadata;
314 foreach my $col (@columns) {
315 my ($first_metadata_obtained, $second_metadata_obtained, $third_metadata_obtained);
316 if (defined $first_metadata_by_col{$col}) {
317 $first_metadata_obtained = $first_metadata_by_col{$col};
318 } else {
319 $first_metadata_obtained = 'undefined';
321 my $first_metadata_expected = $first_expected_metadata{$col};
322 my $first_message = 'trace_history and get_metadata_by_rows tests for '.$col.' for the first element';
323 is ($first_metadata_obtained, $first_metadata_expected, $first_message) or diag "Looks like this failed.";
325 if (defined $second_metadata_by_col{$col}) {
326 $second_metadata_obtained = $second_metadata_by_col{$col};
327 } else {
328 $second_metadata_obtained = 'undefined';
330 my $second_metadata_expected = $second_expected_metadata{$col};
331 my $second_message = 'trace_history and get_metadata_by_rows tests for '.$col.' for the second element';
332 is ($second_metadata_obtained, $second_metadata_expected, $second_message) or diag "Looks like this failed.";
334 if (defined $third_metadata_by_col{$col}) {
335 $third_metadata_obtained = $third_metadata_by_col{$col};
336 } else {
337 $third_metadata_obtained = 'undefined';
339 my $third_metadata_expected = $third_expected_metadata{$col};
340 my $third_message = 'trace_history and get_metadata_by_rows tests for '.$col.' for the third element';
341 is ($third_metadata_obtained, $third_metadata_expected, $third_message) or diag "Looks like this failed.";
344 ## Testing of the find_or_store_function. We are going to create two different metadata object. The first exists into the database
345 ## so the function should return the db object with its id. To this object we are going to change one variable (modification note)
346 ## and we are going to use the same function. Now should insert a new metadata_id.
347 ## Test 44 and 45
349 my $fos_metadata = CXGN::Metadata::Metadbdata->new($schema, $metadata_creation_user);
350 $fos_metadata->set_object_creation_date($general_create_date); ## Now have the same object_create_date and object_create_user
351 $fos_metadata->set_metadata_by_rows({ create_date => $general_create_date, ## We set the same values than the
352 create_person_id => $general_create_person_id, ## third metadata object
353 modified_date => $far_future,
354 modified_person_id => $sp_person_id_for_creation_user,
355 modification_note => 'set_other_data',
356 previous_metadata_id => $last_metadata_id+2,
357 obsolete => 0,
359 my $new_fos_metadata = $fos_metadata->store();
360 my $metadata_test_row = $new_fos_metadata->get_mdmetadata_row();
361 is ($new_fos_metadata->get_metadata_id(), $last_metadata_id+3, 'test for store function with the find result') or
362 diag "Looks like this failed.";
363 $fos_metadata->set_modification_note('set_other_data_for_find_or_store_test');
364 my $newest_fos_metadata = $fos_metadata->store();
365 is ($newest_fos_metadata->get_metadata_id(), $last_metadata_id+4, 'test for store function with store result') or
366 diag "Looks like this failed";
370 ## Check the exists functions
371 ## exists_database_columns function, if exists all the columns return a hash reference with 11 elements. All the values must be 1.
372 ## Test 46
374 my $check_columns_href = $metadata_s->exists_database_columns();
375 my $check_columns_string = join ',', values %{$check_columns_href};
376 is ($check_columns_string, '1,1,1,1,1,1,1,1,1,1,1', 'exists_database_columns test function') or diag "Looks like this failed.";
378 ## exists_metadata check if exists or not a metadata_type in a metadata column. According this, we are going to test if exists
379 ## a metadata_id = last_metadata+10 (should not exists), a metadata_type = modification_note for last_metadata+1 (should not
380 ## exists also) and finally a obsolete_note for metadata_id = $last_metadata_id+2 (should exists).
382 my $check_metadata_id = $metadata_s->exists_metadata($last_metadata_id+10, 'metadata_id');
383 is ($check_metadata_id, 0, 'exists_metadata function for metadata_type = metadata_id test for FALSE result')
384 or diag "Looks like this failed.";
385 my $check_metadata_modification_note = $metadata_s->exists_metadata($last_metadata_id+1, 'modification_note');
386 is ($check_metadata_modification_note, 0, 'exists_metadata function for metadata_type = modification_note for FALSE result')
387 or diag "Looks like this failed";
388 my $check_metadata_obsolete_note = $metadata_s->exists_metadata($last_metadata_id+2, 'obsolete_note');
389 is ($check_metadata_obsolete_note, 0, 'exists_metadata function for metadata_type = obsolete_note for FALSE result')
390 or diag "Looks like this failed";
392 ## Finally we are going to test the enforce_methods
394 my $f_metadata_object = CXGN::Metadata::Metadbdata->new($schema);
395 $f_metadata_object->set_create_date($future);
396 $f_metadata_object->set_create_person_id_by_username($metadata_creation_user);
397 my $new_f_metadata_object = $f_metadata_object->force_insert();
398 my $new_f_metadata_id = $new_f_metadata_object->get_metadata_id();
399 my $new_f_metadata_id_expected = $last_metadata_id+5;
400 is ($new_f_metadata_id, $new_f_metadata_id_expected, 'enforce_insert function test, metadata_id BY DEFAULT')
401 or diag "Looks like this failed.";
402 my $new_f_metadata_create_date = $new_f_metadata_object->get_create_date();
403 is ($new_f_metadata_create_date, $future, 'enforce_insert function test, create_date FORCED')
404 or diag "Looks like this failed.";
405 $new_f_metadata_object->set_create_date($past);
406 my $newest_f_metadata_object = $new_f_metadata_object->force_update();
407 my $newest_f_metadata_id = $newest_f_metadata_object->get_metadata_id();
408 my $newest_f_metadata_create_date = $newest_f_metadata_object->get_create_date();
409 is ($newest_f_metadata_id, $new_f_metadata_id_expected, 'enforce_update function test, metadata_id BY DEFAULT')
410 or diag "Looks like this failed.";
411 is ($newest_f_metadata_create_date, $past, 'enforce_update function test, create_date FORCED')
412 or diag "Looks like this failed.";
414 }; ## End of the eval function
416 if ($@) {
417 print "\nEVAL ERROR:\n\n$@\n";
423 ## RESTORING THE ORIGINAL STATE IN THE DATABASE
424 ## To restore the original state in the database, rollback (it is in a transaction) and set the table_sequence values.
426 $schema->txn_rollback();
428 ## The transaction change the values in the sequence, so if we want set the original value, before the changes
429 ## we have two options:
430 ## 1) SELECT setval (<sequence_name>, $last_value_before_change, true); that said, ok your last true value was...
431 ## 2) SELECT setval (<sequence_name>, $last_value_before_change+1, false); It is false that your last value was ... so the
432 ## next time take the value before this.
434 ## The option 1 leave the seq information in a original state except if there aren't any value in the seq, that it is
435 ## more as the option 2
437 ## But the tests do not reset the sequences anymore.
439 #####
440 1; ##
441 #####