Merge pull request #42 from solgenomics/topic/duplicate_image_warning
[cxgn-corelibs.git] / t / CXGN / Metadata / dbiref.t
blob0b12c2cf6dcd397044676ad6ede10ccad79c6e6c
1 #!/usr/bin/perl
3 =head1 NAME
5 dbiref.t
6 A piece of code to test the CXGN::Metadata::Dbiref module
8 =cut
10 =head1 SYNOPSIS
12 perl Dbiref.t
14 Note: To run the complete test the database connection should be done as
15 postgres user
16 (web_usr have not privileges to insert new data into the sed tables)
18 prove Dbiref.t
20 this test need some environment variables:
22 export METADATA_TEST_METALOADER='metaloader user'
23 export METADATA_TEST_DBDSN='database dsn as:
24 dbi:DriverName:database=database_name;host=hostname;port=port'
26 example:
27 export METADATA_TEST_DBDSN='dbi:Pg:database=sandbox;host=localhost;'
29 export METADATA_TEST_DBUSER='database user with insert permissions'
30 export METADATA_TEST_DBPASS='database password'
32 =head1 DESCRIPTION
34 This script check XX variables to test the right operation of the
35 CXGN::Metadata::DBipath module:
37 + test 1 and 3: Test for module use
38 + test from 4 to 7: Test to set data into the object without any storage
39 + test 8 and 9: Test store function for a new row
40 + test 10 and 11: Test store related with metadata for dbipath and dbiref
41 + test 12: Test get_dbipath_obj function
42 + test 13: Test set_dbipath_id_by_dbipath_elements
43 + test 14 to 23: Test the store function for a modification case.
44 Checking the metadbdata.
45 + test 24: Testing constructor new with a id
46 + test 25: Testing is_obsolete function
47 + test 26: Testing obsolete function
48 + test from 27 to 36: Testing the metadbdata associated to obsolete change
49 + test 37: Testing the revert tag for the obsolete function
50 + test 38 to 47: Testing the metadbdata associated with the revert change
51 + test 48: Testing new_by_accession constructor
53 =cut
55 =head1 AUTHORS
57 Aureliano Bombarely Gomez
58 (ab782@cornell.edu)
60 =cut
63 use strict;
64 use warnings;
66 use Data::Dumper;
67 use Test::More; # use qw | no_plan | while developing the tests
69 use CXGN::DB::Connection;
71 ## The tests still need search_path
73 my @schema_list = ('metadata', 'public');
74 my $schema_list = join(',', @schema_list);
75 my $set_path = "SET search_path TO $schema_list";
77 ## First check env. variables and connection
79 BEGIN {
81 ## Env. variables have been changed to use biosource specific ones
83 my @env_variables = qw/METADATA_TEST_METALOADER METADATA_TEST_DBDSN METADATA_TEST_DBUSER METADATA_TEST_DBPASS/;
85 for my $env (@env_variables) {
86 unless (defined $ENV{$env}) {
87 plan skip_all => "Environment variable $env not set, aborting";
91 eval {
92 CXGN::DB::Connection->new(
93 $ENV{METADATA_TEST_DBDSN},
94 $ENV{METADATA_TEST_DBUSER},
95 $ENV{METADATA_TEST_DBPASS},
96 {on_connect_do => $set_path}
97 );
100 if ($@ =~ m/DBI connect/) {
102 plan skip_all => "Could not connect to database";
105 plan tests => 48;
108 BEGIN {
109 use_ok('CXGN::Metadata::Schema'); ## TEST1
110 use_ok('CXGN::Metadata::Dbiref'); ## TEST2
111 use_ok('CXGN::Metadata::Metadbdata'); ## TEST3
115 #if we cannot load the CXGN::Metadata::Schema module, no point in continuing
116 CXGN::Metadata::Schema->can('connect')
117 or BAIL_OUT('could not load the CXGN::Metadata::Schema module');
119 ## Prespecified variable
121 my $metadata_creation_user = $ENV{METADATA_TEST_METALOADER};
123 ## The biosource schema contain all the metadata classes so don't need to create another Metadata schema
124 ## CXGN::DB::DBICFactory is obsolete, it has been replaced by CXGN::Metadata::Schema
126 my $schema = CXGN::Metadata::Schema->connect( $ENV{METADATA_TEST_DBDSN},
127 $ENV{METADATA_TEST_DBUSER},
128 $ENV{METADATA_TEST_DBPASS},
129 {on_connect_do => $set_path});
131 $schema->txn_begin();
133 ## Get the last values
134 my %nextvals = $schema->get_nextval();
135 my $last_metadata_id = $nextvals{'md_metadata'};
136 my $last_dbipath_id = $nextvals{'md_dbipath'};
137 my $last_dbiref_id = $nextvals{'md_dbiref'};
139 ## Create a empty metadata object to use in the database store functions
140 my $metadbdata = CXGN::Metadata::Metadbdata->new($schema, $metadata_creation_user);
141 my $creation_date = $metadbdata->get_object_creation_date();
142 my $creation_user_id = $metadbdata->get_object_creation_user_by_id();
145 ## FIRST TEST BLOCK (TEST FROM 4 TO 7)
146 ## This is the first group of tests, to check if an empty object can store and after can return the data
147 ## Create a new empty object (It is not necessary add any dbipath_id becuase it don't interact with the db;
149 my $dbiref = CXGN::Metadata::Dbiref->new($schema, undef);
151 ## Load of the eight different parameters for an empty object using a hash with keys=root name for tha function and
152 ## values=value to test
154 my %test_values_for_empty_object=( dbiref_id => $last_dbiref_id+1,
155 iref_accession => $last_dbipath_id+1,
156 accession => $last_dbipath_id+1, ## A synonym for iref_accession
157 dbipath_id => $last_dbipath_id+1,
160 ## Load the data in the empty object
161 my @function_keys = sort keys %test_values_for_empty_object;
162 foreach my $rootfunction (@function_keys) {
163 my $setfunction = 'set_' . $rootfunction;
164 if ($rootfunction eq 'dbiref_id') {
165 $setfunction = 'force_set_' . $rootfunction;
167 $dbiref->$setfunction($test_values_for_empty_object{$rootfunction});
169 ## Get the data from the object and store in two hashes. The first %getdata with keys=root_function_name and
170 ## value=value_get_from_object and the second, %testname with keys=root_function_name and values=name for the test.
172 my (%getdata, %testnames);
173 foreach my $rootfunction (@function_keys) {
174 my $getfunction = 'get_'.$rootfunction;
175 my $data = $dbiref->$getfunction();
176 $getdata{$rootfunction} = $data;
177 my $testname = 'BASIC SET/GET FUNCTION for ' . $rootfunction.' test';
178 $testnames{$rootfunction} = $testname;
181 ## And now run the test for each function and value
183 foreach my $rootfunction (@function_keys) {
184 is($getdata{$rootfunction}, $test_values_for_empty_object{$rootfunction}, $testnames{$rootfunction})
185 or diag "Looks like this failed.";
188 ## SECOND BLOCK, Interactions with the DB for metadata object
190 eval {
192 ## First, the store functions check if exists a dbipath_id into the database, so it will create a dbipath id
193 ## for the path 'metadata.md_dbipath.dbipath_id' (with itself to be sure that it don't exists into the database)
195 ### It will create a new object based in dbipath
196 my $dbipath = CXGN::Metadata::Dbipath->new_by_path($schema, ['metadata', 'md_dbipath', 'dbipath_id']);
197 my $dbipath_stored = $dbipath->store($metadbdata);
198 my $dbipath_id = $dbipath_stored->get_dbipath_id();
200 ## New, it will create the dbiref object (TEST 8 and 9)
201 my $dbiref2 = CXGN::Metadata::Dbiref->new($schema, undef);
202 $dbiref2->set_accession($dbipath_id);
203 $dbiref2->set_dbipath_id($dbipath_id);
204 my $dbiref2_stored = $dbiref2->store($metadbdata);
205 is($dbiref2_stored->get_accession(), $last_dbipath_id+1, 'STORE FUNCTION for a new row, checking iref_accession')
206 or diag "Looks like this failed";
207 is($dbiref2_stored->get_dbipath_id(), $last_dbipath_id+1, 'STORE FUNCTION for a new row, checking dbipath_id')
208 or diag "Looks like this failed";
210 my $test5 = $dbiref2_stored->get_dbipath_id();
212 ## Check the metadata for dbipath and dbiref (TEST 10 and 11)
213 ## The metadata should be the same because both were created at the same time (with the same metadbdata)
214 my $dbipath_metadata_id = $dbipath_stored->get_metadbdata()->get_metadata_id();
215 my $dbiref_metadata_id = $dbiref2_stored->get_metadbdata()->get_metadata_id();
216 is($dbipath_metadata_id, $last_metadata_id+1, 'STORE FUNCTION METADATA RELATED, checking metadata_id for a new dbipath')
217 or diag "Looks like this failed";
218 is($dbiref_metadata_id, $last_metadata_id+1, 'STORE FUNCTION METADATA RELATED, checking metadata_id for a new dbiref')
219 or diag "Looks like this failed";
221 ## Testing get_dbipath_obj function (TEST 12)
222 my $dbipath2 = $dbiref2_stored->get_dbipath_obj();
223 my @dbipath_elements = $dbipath2->get_dbipath();
224 my $dbipath_elements = join('.', @dbipath_elements);
225 is($dbipath_elements, 'metadata.md_dbipath.dbipath_id', 'GET DBIPATH_OBJ FUNCTION, checking the dbipath elements')
226 or diag "Looks like this failed";
228 ## Testing set_dbipath_id_by_dbipath_elements (TEST 13)
229 ## Before it need a different dbipath row to set
230 my $dbipath3 = CXGN::Metadata::Dbipath->new_by_path($schema, ['metadata', 'md_dbiref', 'dbiref_id']);
231 my $dbipath3_stored = $dbipath3->store($metadbdata);
232 my $dbipath3_id = $dbipath3_stored->get_dbipath_id();
234 $dbiref2_stored->set_dbipath_id_by_dbipath_elements(['metadata', 'md_dbiref', 'dbiref_id']);
235 is($dbiref2_stored->get_dbipath_id(), $dbipath3_id, 'SET DBIPATH ID BY DBIPATH ELEMENTS, checking the new dbipath_id')
236 or diag "Looks like this failed";
238 ## Now test store for a modification checking the metadbdata (TEST 14 to 23)
239 my $dbiref3_stored = $dbiref2_stored->store($metadbdata);
240 my $dbiref3_metadbdata = $dbiref3_stored->get_metadbdata();
241 my %metadbdata3 = $dbiref3_metadbdata->get_metadata_by_rows();
242 my %expected_metadata3 = ( metadata_id => $last_metadata_id+2,
243 create_date => $creation_date,
244 create_person_id => $creation_user_id,
245 modified_date => $creation_date,
246 modified_person_id => $creation_user_id,
247 modification_note => 'set value in dbipath_id column',
248 previous_metadata_id => $last_metadata_id+1,
249 obsolete => 0
251 foreach my $st_metadata_type3 (keys %metadbdata3) {
252 my $message3 = "STORE FUNCTION METADBDATA INTERACTION FOR MODIFICATIONS, get_metadbdata test, checking $st_metadata_type3";
253 is($metadbdata3{$st_metadata_type3}, $expected_metadata3{$st_metadata_type3}, $message3) or diag "Looks like this failed";
256 ## Get a new dbiref using id (TEST 24)
257 my $dbiref4 = CXGN::Metadata::Dbiref->new($schema, $dbiref2_stored->get_dbiref_id());
258 is($dbiref4->get_accession(), $dbiref2_stored->get_accession(), 'CONSTRUCTOR NEW using a dbxref_id, checking iref_accession')
259 or diag "Looks like this failed";
261 ## Testing the obsolete features
262 ## Checking the is_obsolete function (TEST 25)
263 my $obsolete = $dbiref4->is_obsolete();
264 is($obsolete, 0,"IS OBSOLETE FUNCTION TEST") or diag "Looks like this failed";
266 ## Test the obsolete function (TEST 26)
267 my $dbiref5_obsolete = $dbiref4->obsolete($metadbdata, 'change to obsolete test');
268 my $obsolete2 = $dbiref5_obsolete->is_obsolete();
269 is($obsolete2, 1,"OBSOLETE FUNCTION TEST") or diag "Looks like this failed";
271 ## Checking the metadata associated to this obsolete change (TEST 27 to 36)
272 my $metadbdata5 = $dbiref5_obsolete->get_metadbdata();
273 my %metadbdata5 = $metadbdata5->get_metadata_by_rows();
274 my %expected_metadata5 = ( metadata_id => $last_metadata_id+3,
275 create_date => $creation_date,
276 create_person_id => $creation_user_id,
277 modified_date => $creation_date,
278 modified_person_id => $creation_user_id,
279 modification_note => 'change to obsolete',
280 previous_metadata_id => $last_metadata_id+2,
281 obsolete => 1,
282 obsolete_note => 'change to obsolete test'
284 foreach my $metadata_type5 (keys %metadbdata5) {
285 my $message5 = "STORE FUNCTION METADBDATA INTERACTION FOR OBSOLETE, get_metadbdata test, checking $metadata_type5";
286 is($metadbdata5{$metadata_type5}, $expected_metadata5{$metadata_type5}, $message5) or diag "Looks like this failed";
289 ## Test the REVERT tag for the obsolete function (TEST 37)
290 my $dbiref5_revert = $dbiref5_obsolete->obsolete($metadbdata, 'revert obsolete test', 'REVERT');
291 my $obsolete3 = $dbiref5_revert->is_obsolete();
292 is($obsolete3, 0,"OBSOLETE FUNCTION TEST") or diag "Looks like this failed";
294 ## Checking the metadata associated to this obsolete change (TEST 38 to 47)
295 my $metadbdata6 = $dbiref5_revert->get_metadbdata();
296 my %metadbdata6 = $metadbdata6->get_metadata_by_rows();
297 my %expected_metadata6 = ( metadata_id => $last_metadata_id+4,
298 create_date => $creation_date,
299 create_person_id => $creation_user_id,
300 modified_date => $creation_date,
301 modified_person_id => $creation_user_id,
302 modification_note => 'revert obsolete',
303 previous_metadata_id => $last_metadata_id+3,
304 obsolete => 0,
305 obsolete_note => 'revert obsolete test'
307 foreach my $metadata_type6 (keys %metadbdata6) {
308 my $message6 = "STORE FUNCTION METADBDATA INTERACTION FOR REVERT OBSOLETE, get_metadbdata test, checking $metadata_type6";
309 is($metadbdata6{$metadata_type6}, $expected_metadata6{$metadata_type6}, $message6) or diag "Looks like this failed";
312 ## Testing new_by_accession constructor (TEST 48).
313 ## It will use the first dbiref object stored with accession=$dbipath_id and path = ['metadata', 'md_dbipath', dbipath_id]
314 ## It should return an object with dbiref_id= $last_dbiref_id+1
316 my $dbiref6 = CXGN::Metadata::Dbiref->new_by_accession( $schema,
317 $dbiref2_stored->get_accession(),
318 ['metadata', 'md_dbiref', 'dbiref_id'] ); ## It was modificated
320 is($dbiref6->get_dbiref_id(), $last_dbiref_id+1, "NEW_BY_ACCESSION constructor, checking dbiref_id")
321 or diag "Looks like this failed";
324 }; ## End of the eval function
327 if ($@) {
328 print "\nEVAL ERROR:\n\n$@\n";
332 ## RESTORING THE ORIGINAL STATE IN THE DATABASE
333 ## To restore the original state in the database, rollback (it is in a transaction) and set the table_sequence values.
335 $schema->txn_rollback();
337 ## The transaction change the values in the sequence, so if we want set the original value, before the changes
338 ## we have two options:
339 ## 1) SELECT setval (<sequence_name>, $last_value_before_change, true); that said, ok your last true value was...
340 ## 2) SELECT setval (<sequence_name>, $last_value_before_change+1, false); It is false that your last value was ... so the
341 ## next time take the value before this.
343 ## The option 1 leave the seq information in a original state except if there aren't any value in the seq, that it is
344 ## more as the option 2
346 ## These tests do not reset the db sequences anymore
348 ####
349 1; #
350 ####