fixed the pod for add_child. This function does not take any arguments. it generates...
[cxgn-corelibs.git] / t / CXGN / Metadata / groups.t
blobaea89e1456749e656cb6f4e3ee044db3411151d8
1 #!/usr/bin/perl
3 =head1 NAME
5 groups.t
6 A piece of code to test the CXGN::Metadata::Groups module
8 =cut
10 =head1 SYNOPSIS
12 perl Groups.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 Groups.t
20 this test need some environment variables:
21 export GEMTEST_METALOADER= 'metaloader user'
22 export GEMTEST_DBUSER= 'database user with insert permissions'
23 export GEMTEST_DBPASS= 'database password'
25 also is recommendable set the reset dbseq after run the script
26 export RESET_DBSEQ=1
28 if it is not set, after one run all the test that depends of a primary id
29 (as metadata_id) will fail because it is calculated based in the last
30 primary id and not in the current sequence for this primary id
32 =head1 DESCRIPTION
34 This script check XX variables to test the right operation of the
35 CXGN::Metadata::Groups module:
37 + Tests from 1 to 4 - use of modules;
38 + Tests from 5 to 8 - BASIC SET/GET FUNCTIONS
39 + Test 9 - STORE FUNCTION with a new group row
40 + Tests from 10 to 19 - STORE FUNCTION METADBDATA INTERACTION
41 + Test 20 - IS OBSOLETE FUNCTION TEST
42 + Test 21 and 22 - STORE FUNCTION with a modified group row
43 + Tests from 23 to 32 - STORE FUNCTION METADBDATA INTERACTION FOR MODIFICATIONS
44 + Test 33 - OBSOLETE FUNCTION TEST
45 + Tests from 34 to 43 - STORE FUNCTION METADBDATA INTERACTION FOR OBSOLETE
46 + Test 44 - REVERT OBSOLETE FUNCTION TEST
47 + Test from 45 to 54 - STORE FUNCTION METADBDATA INTERACTION FOR REVERT OBSOLETE
48 + Test from 55 to 61 - SET/GET MEMBER
49 + Test from 62 to 94 - STORE MEMBERS and STORE FUNCTION METADBDATA FOR MEMBER
50 + Test 95 and 96 - OBSOLETE MEMBER FUNCTION
51 + Test 97 - NEW_BY_GROUP_NAME CONSTRUCTOR
52 + Test 98 - ADD MEMBER METHOD,
53 + Test 99 - GENERAL STORE FUNCTION,
54 + Test 100 - GET MEMBERS FUNCTION with OBSOLETE TAG,
55 + Test 101 - GET MEMBERS FUNCTION with NON OBSOLETE TAG
56 + Test 102 - Warning for new_by_member
57 + Test 103 - New_by_member
59 =cut
61 =head1 AUTHORS
63 Aureliano Bombarely Gomez
64 (ab782@cornell.edu)
66 =cut
69 use strict;
70 use warnings;
72 use Data::Dumper;
73 use Test::More tests => 103 ;# qw | no_plan |; # while developing the test
74 use Test::Exception;
75 use Test::Warn;
77 use CXGN::DB::Connection;
78 use CXGN::DB::DBICFactory;
80 BEGIN {
81 use_ok('CXGN::Metadata::Schema'); ## TEST1
82 use_ok('CXGN::Metadata::Groups'); ## TEST2
83 use_ok('CXGN::Metadata::Metadbdata'); ## TEST3
84 use_ok('CXGN::Metadata::Dbiref') ## TEST4
87 ## Check the environment variables
88 my @env_variables = ('GEMTEST_METALOADER', 'GEMTEST_DBUSER', 'GEMTEST_DBPASS', 'RESET_DBSEQ');
89 foreach my $env (@env_variables) {
90 unless ($ENV{$env} =~ m/^\w+/) {
91 print STDERR "ENVIRONMENT VARIABLE WARNING: Environment variable $env was not set for this test. Use perldoc for more info.\n";
95 #if we cannot load the CXGN::Metadata::Schema module, no point in continuing
96 CXGN::Metadata::Schema->can('connect')
97 or BAIL_OUT('could not load the CXGN::Metadata::Schema module');
99 ## Prespecified variable
101 my $metadata_creation_user = $ENV{GEMTEST_METALOADER};
103 ## The triggers need to set the search path to tsearch2 in the version of psql 8.1
104 my $psqlv = `psql --version`;
105 chomp($psqlv);
107 my @schema_list = ('metadata', 'public');
108 if ($psqlv =~ /8\.1/) {
109 push @schema_list, 'tsearch2';
112 my $schema = CXGN::DB::DBICFactory->open_schema( 'CXGN::Metadata::Schema',
113 search_path => \@schema_list,
114 dbconn_args =>
116 dbuser => $ENV{GEMTEST_DBUSER},
117 dbpass => $ENV{GEMTEST_DBPASS},
121 $schema->txn_begin();
124 ## Get the last values
125 my $all_last_ids_href = $schema->get_all_last_ids($schema);
126 my %last_ids = %{$all_last_ids_href};
127 my $last_metadata_id = $last_ids{'metadata.md_metadata_metadata_id_seq'};
128 my $last_group_id = $last_ids{'metadata.md_groups_group_id_seq'};
129 my $last_dbiref_id = $last_ids{'metadata.md_dbiref_dbiref_id_seq'};
131 ## Create a empty metadata object to use in the database store functions
132 my $metadbdata = CXGN::Metadata::Metadbdata->new($schema, $metadata_creation_user);
133 my $creation_date = $metadbdata->get_object_creation_date();
134 my $creation_user_id = $metadbdata->get_object_creation_user_by_id();
136 ## FIRST TEST BLOCK (TEST FROM 5 TO 8)
137 ## This is the first group of tests, to check if an empty object can store and after can return the data
138 ## Create a new empty object;
140 my $group = CXGN::Metadata::Groups->new($schema, undef);
142 ## Load of the eight different parameters for an empty object using a hash with keys=root name for tha function and
143 ## values=value to test
145 my %test_values_for_empty_object=( group_id => $last_group_id+1,
146 group_name => 'group test',
147 group_type => 'dbipath',
148 group_description => 'group testing using dbipaths',
151 ## Load the data in the empty object
152 my @function_keys = sort keys %test_values_for_empty_object;
153 foreach my $rootfunction (@function_keys) {
154 my $setfunction = 'set_' . $rootfunction;
155 if ($rootfunction eq 'group_id') {
156 $setfunction = 'force_set_' . $rootfunction;
158 $group->$setfunction($test_values_for_empty_object{$rootfunction});
160 ## Get the data from the object and store in two hashes. The first %getdata with keys=root_function_name and
161 ## value=value_get_from_object and the second, %testname with keys=root_function_name and values=name for the test.
163 my (%getdata, %testnames);
164 foreach my $rootfunction (@function_keys) {
165 my $getfunction = 'get_'.$rootfunction;
166 my $data = $group->$getfunction();
167 $getdata{$rootfunction} = $data;
168 my $testname = 'BASIC SET/GET FUNCTION for ' . $rootfunction.' test';
169 $testnames{$rootfunction} = $testname;
172 ## And now run the test for each function and value
174 foreach my $rootfunction (@function_keys) {
175 is($getdata{$rootfunction}, $test_values_for_empty_object{$rootfunction}, $testnames{$rootfunction})
176 or diag "Looks like this failed.";
179 ### SECOND TEST BLOCK
180 ### Use of store functions.
182 eval {
184 ### It will create a new object based in dbipath (TEST 9)
185 my $group2 = CXGN::Metadata::Groups->new($schema);
186 $group2->set_group_name('group test2');
187 $group2->set_group_type('dbipath');
188 $group2->set_group_description('group testing using dbipaths');
190 ### It will store it
192 my $group3_stored = $group2->store_group($metadbdata);
193 my $group3_id = $group3_stored->get_group_id();
195 is($group3_id, $last_group_id+1, 'STORE FUNCTION with a new group row, checking group_id')
196 or diag "Looks like this failed";
198 ## Checking the metadbdata associated to this new creation (TEST 10 to 19)
200 my $metadbdata3 = $group3_stored->get_metadbdata();
201 my %metadbdata3 = $metadbdata3->get_metadata_by_rows();
203 my %expected_metadata3 = ( metadata_id => $last_metadata_id+1,
204 create_date => $creation_date,
205 create_person_id => $creation_user_id,
206 obsolete => 0
209 foreach my $metadata_type3 (keys %metadbdata3) {
210 my $message3 = "STORE FUNCTION METADBDATA INTERACTION, get_metadbdata test, checking $metadata_type3";
212 is($metadbdata3{$metadata_type3}, $expected_metadata3{$metadata_type3}, $message3)
213 or diag "Looks like this failed";
216 ## Checking the is_obsolete function (TEST 20)
218 my $obsolete = $group3_stored->is_obsolete();
219 is($obsolete, 0,"IS OBSOLETE FUNCTION TEST") or diag "Looks like this failed";
221 ## Testing a modification in the row data (TEST 21 and 22)
223 $group3_stored->set_group_description('testing modifications in the description');
224 my $group4_modified = $group3_stored->store_group($metadbdata);
225 my $group4_id = $group4_modified->get_group_id();
227 is($group4_id, $last_group_id+1, 'STORE FUNCTION with a modified group row, checking group_id')
228 or diag "Looks like this failed";
230 my $group4_desc = $group4_modified->get_group_description();
231 is($group4_desc, 'testing modifications in the description', 'STORE FUNCTION with a modified group row, checking group_description')
232 or diag "Looks like this failed";
234 ## Checking the metadbdata associated to this modification (TEST 23 to 32)
236 my $metadbdata4 = $group4_modified->get_metadbdata();
237 my %metadbdata4 = $metadbdata4->get_metadata_by_rows();
238 my %expected_metadata4 = ( metadata_id => $last_metadata_id+2,
239 create_date => $creation_date,
240 create_person_id => $creation_user_id,
241 modified_date => $creation_date,
242 modified_person_id => $creation_user_id,
243 modification_note => 'set value in group_description column',
244 previous_metadata_id => $last_metadata_id+1,
245 obsolete => 0
248 foreach my $metadata_type4 (keys %metadbdata4) {
249 my $message4 = "STORE FUNCTION METADBDATA INTERACTION FOR MODIFICATIONS, get_metadbdata test, checking $metadata_type4";
250 is($metadbdata4{$metadata_type4}, $expected_metadata4{$metadata_type4}, $message4) or diag "Looks like this failed";
253 ## Test the obsolete function (TEST 33)
255 my $group5_obsolete = $group4_modified->obsolete_group($metadbdata, 'change to obsolete test');
256 my $obsolete5 = $group5_obsolete->is_obsolete();
257 is($obsolete5, 1,"OBSOLETE FUNCTION TEST") or diag "Looks like this failed";
259 ## Checking the metadata associated to this obsolete change (TEST 34 to 43)
261 my $metadbdata5 = $group5_obsolete->get_metadbdata();
262 my %metadbdata5 = $metadbdata5->get_metadata_by_rows();
263 my %expected_metadata5 = ( metadata_id => $last_metadata_id+3,
264 create_date => $creation_date,
265 create_person_id => $creation_user_id,
266 modified_date => $creation_date,
267 modified_person_id => $creation_user_id,
268 modification_note => 'change to obsolete',
269 previous_metadata_id => $last_metadata_id+2,
270 obsolete => 1,
271 obsolete_note => 'change to obsolete test'
274 foreach my $metadata_type5 (keys %metadbdata5) {
276 my $message5 = "STORE FUNCTION METADBDATA INTERACTION FOR OBSOLETE, get_metadbdata test, checking $metadata_type5";
277 is($metadbdata5{$metadata_type5}, $expected_metadata5{$metadata_type5}, $message5) or diag "Looks like this failed";
280 ## Test the REVERT tag for the obsolete function (TEST 44)
282 my $group6_revert = $group5_obsolete->obsolete_group($metadbdata, 'revert obsolete test', 'REVERT');
283 my $obsolete6 = $group6_revert->is_obsolete();
284 is($obsolete6, 0,"REVERT OBSOLETE FUNCTION TEST") or diag "Looks like this failed";
286 ## Checking the metadata associated to this obsolete change (TEST 45 to 54)
288 my $metadbdata6 = $group6_revert->get_metadbdata();
289 my %metadbdata6 = $metadbdata6->get_metadata_by_rows();
290 my %expected_metadata6 = ( metadata_id => $last_metadata_id+4,
291 create_date => $creation_date,
292 create_person_id => $creation_user_id,
293 modified_date => $creation_date,
294 modified_person_id => $creation_user_id,
295 modification_note => 'revert obsolete',
296 previous_metadata_id => $last_metadata_id+3,
297 obsolete => 0,
298 obsolete_note => 'revert obsolete test'
301 foreach my $metadata_type6 (keys %metadbdata6) {
302 my $message6 = "STORE FUNCTION METADBDATA INTERACTION FOR REVERT OBSOLETE, get_metadbdata test, checking $metadata_type6";
304 is($metadbdata6{$metadata_type6}, $expected_metadata6{$metadata_type6}, $message6) or diag "Looks like this failed";
307 ### THIRD BLOCK, test the member code
309 ## First, we need to add some dbiref's. It will create three based in md_metadata table with the metadata_id
310 ## created before. (TEST 55 to 61)
312 my @dbiref_list =();
313 my @metadata_ids = ($last_metadata_id+2, $last_metadata_id+3, $last_metadata_id+4);
315 my $dbipath_id = CXGN::Metadata::Dbipath->new_by_path( $schema,
316 ['metadata', 'md_metadata', 'metadata_id'] )
317 ->store($metadbdata)
318 ->get_dbipath_id();
320 foreach my $met_id (@metadata_ids) {
321 my $dbiref = CXGN::Metadata::Dbiref->new($schema, undef);
322 $dbiref->set_accession($met_id);
323 $dbiref->set_dbipath_id($dbipath_id);
325 my $dbiref_id = $dbiref->store($metadbdata)
326 ->get_dbiref_id();
328 push @dbiref_list, $dbiref_id;
331 my $group7 = CXGN::Metadata::Groups->new($schema, $last_group_id+1);
332 $group7->set_member_ids(\@dbiref_list);
334 my @member_ids = $group7->get_member_ids();
335 my $obj_member_ids = join(',', sort @member_ids);
336 my $exp_member_ids = join(',', sort @dbiref_list);
338 is($obj_member_ids, $exp_member_ids, 'SET/GET MEMBER IDS over the group object, checking dbiref_id list')
339 or diag "Looks like this failed";
341 my @members = $group7->get_members();
342 my $n = 0;
344 foreach my $member (@members) {
345 my @dbipath_elements = $member->get_dbipath_obj()
346 ->get_dbipath();
348 my $g_dbipath_name = join('.', @dbipath_elements);
349 my $g_accession = $member->get_accession();
351 my $c = $n + 1;
352 is($g_accession, $metadata_ids[$n], "SET/GET MEMBER $c the group object, checking dbiref object (dbiref_id)")
353 or diag "Looks like this failed";
355 $n++;
357 is($g_dbipath_name, 'metadata.md_metadata.metadata_id', "SET/GET MEMBER $c over group object, checking dbiref object (dbipath)")
358 or diag "Looks like this failed";
361 ## Test store member functions (TEST 62 to 94)
363 my $group8_stored = $group7->store_members($metadbdata);
364 my @stored_members = $group8_stored->get_members();
365 my %member_metadata = $group8_stored->get_metadbdata_for_members($metadbdata);
367 my $test1 = join(',', keys %member_metadata);
368 my $test2 = join(',', values %member_metadata);
371 my $m = 0;
373 foreach my $stored_member (@stored_members) {
374 my $s_accession = $stored_member->get_accession();
375 my $s_dbiref_id = $stored_member->get_dbiref_id();
377 my $d = $m + 1;
378 is($s_accession, $metadata_ids[$m], "STORE MEMBERS ($d) the group object, checking dbiref object (dbiref_id)")
379 or diag "Looks like this failed";
381 $m++;
383 my %member_metadbdata8 = $member_metadata{$s_dbiref_id}->get_metadata_by_rows();
384 my %expected_metadata8 = ( metadata_id => $last_metadata_id+1,
385 create_date => $creation_date,
386 create_person_id => $creation_user_id,
387 obsolete => 0,
389 foreach my $metadata_type8 (keys %member_metadbdata8) {
390 my $message8 = "STORE FUNCTION METADBDATA FOR MEMBER ($d), get_metadbdata test, checking $metadata_type8";
392 is($member_metadbdata8{$metadata_type8}, $expected_metadata8{$metadata_type8}, $message8) or diag "Looks like this failed";
396 ### Test obsolete member... and imagine that i don't remember the dbiref_id for the accession=$last_metadata_id+2 (TEST 95, 96)
398 my $obsolete_dbiref_id = CXGN::Metadata::Dbiref->new_by_accession( $schema,
399 $last_metadata_id+2,
400 ['metadata',
401 'md_metadata',
402 'metadata_id'] )
403 ->get_dbiref_id();
404 my $non_obsolete_dbiref_id = CXGN::Metadata::Dbiref->new_by_accession( $schema,
405 $last_metadata_id+3,
406 ['metadata',
407 'md_metadata',
408 'metadata_id'] )
409 ->get_dbiref_id();
411 my $group9 = $group8_stored->obsolete_member( $metadbdata,
412 $obsolete_dbiref_id,
413 'obsolete a member test'
415 my $obsolete_member1 = $group9->is_obsolete_member( $obsolete_dbiref_id );
416 is($obsolete_member1, 1, "OBSOLETE MEMBER FUNCTION, is_obsolete_member test, ckecking boolean, true")
417 or diag "Looks like this failed";
418 my $obsolete_member2 = $group9->is_obsolete_member( $non_obsolete_dbiref_id );
419 is($obsolete_member2, 0, "OBSOLETE MEMBER FUNCTION, is_obsolete_member test, ckecking boolean, false")
420 or diag "Looks like this failed";
422 ### Test new_by_group_name (TEST 97)
424 my $group_name = $group7->get_group_name();
426 my $group10 = CXGN::Metadata::Groups->new_by_group_name($schema, $group_name);
428 is($group10->get_group_id(), $last_group_id+1, "NEW_BY_GROUP_NAME CONSTRUCTOR, checking group_id")
429 or diag "Looks like this failed";
431 ## Test add a member
433 ## It will create an empty object and set the values instead to create the object with these values
434 ## because when it is created a new object with an accession that do not exists into the database return
435 ## a warning message
437 my $new_dbiref = CXGN::Metadata::Dbiref->new( $schema );
438 $new_dbiref->set_accession($last_metadata_id+1);
439 $new_dbiref->set_dbipath_id_by_dbipath_elements( ['metadata', 'md_metadata', 'metadata_id'] );
441 my $new_dbiref_id = $new_dbiref->store($metadbdata)
442 ->get_dbiref_id();
444 my $group11 = $group10->add_member($new_dbiref_id)
445 ->store($metadbdata);
447 my @accessions = ();
449 my @m_members = $group11->get_members();
450 foreach my $m_member (@m_members) {
451 my $accession = $m_member->get_accession();
452 push @accessions, $accession;
455 ## The members should be the @metadata_ids + this $last_metadata_id+4 (TEST 98)
457 push @metadata_ids, $last_metadata_id+1;
458 my $expected_members = join(',', sort {$a <=> $b} @metadata_ids);
459 my $obtained_members = join(',', sort {$a <=> $b} @accessions);
460 is($obtained_members, $expected_members, "ADD MEMBER METHOD, cheking a list of member (dbiref_ids)")
461 or diag "Looks like this failed";
463 ## Group11 also should have a group_id = $last_group_id+1 (TEST 99)
465 is($group11->get_group_id(), $last_group_id+1, "GENERAL STORE FUNCTION, checking group_id")
466 or diag "Looks like this failed";
468 ## Check the obsolete tag to get members, it will take $last_metadata_id+2, (TEST 100)
469 my @obsolete_members = $group11->get_members('OBSOLETE');
470 my $obs_accession = $obsolete_members[0]->get_accession();
472 is($obs_accession, $last_metadata_id+2, "GET MEMBERS FUNCTION with OBSOLETE TAG, checking accessions for members")
473 or diag "Looks like this failed";
475 ## Test the non obsolete too (TEST 101)
476 my @non_obsolete_members = $group11->get_members('NON_OBSOLETE');
478 my @non_obsolete_acc = ();
479 foreach my $non_obsolete_member (@non_obsolete_members) {
480 my $non_obs_acc = $non_obsolete_member->get_accession();
481 push @non_obsolete_acc, $non_obs_acc;
484 my $obtained_non_obs = join(',', sort {$a <=> $b} @non_obsolete_acc);
485 my $expected_non_obs = join(',', sort {$a <=> $b} ($last_metadata_id+3, $last_metadata_id+4, $last_metadata_id+1 ) );
487 is($obtained_non_obs, $expected_non_obs,
488 "GET MEMBERS FUNCTION with NON OBSOLETE TAG, checking accessions for members")
489 or diag "Looks like this failed";
492 ## Testing new by members.
494 my @members12 = ();
495 foreach my $m_metadata_id (@metadata_ids) {
496 my $m_dbiref_id = CXGN::Metadata::Dbiref->new_by_accession( $schema,
497 $m_metadata_id,
498 ['metadata',
499 'md_metadata',
500 'metadata_id'] )
501 ->get_dbiref_id();
502 push @members12, $m_dbiref_id;
505 ## Now it will add a new member ($last_metadata_id+2)
507 my $other_dbiref = CXGN::Metadata::Dbiref->new( $schema );
508 $other_dbiref->set_accession($last_metadata_id+2);
509 $other_dbiref->set_dbipath_id_by_dbipath_elements( ['metadata', 'md_metadata', 'metadata_id'] );
511 my $other_dbiref_id = $other_dbiref->store($metadbdata)
512 ->get_dbiref_id();
514 push @members12, $other_dbiref_id;
516 my $group12;
517 warning_like { $group12 = CXGN::Metadata::Groups->new_by_members($schema, \@members12); } qr/DATABASE COHERENCE/,
518 'TESTING WARNING ERROR when does not exist group with the specified elements into the database';
520 my $group12_id = $group12->get_group_id();
522 ## This is to test if fail to find the group to store the new group and check the new group_id
523 unless (defined $group12_id) {
524 $group12_id = $group12->store($metadbdata)
525 ->get_group_id();
528 is($group12_id, $last_group_id+2, "NEW_BY_MEMBERS CONSTRUCTOR, checking the group_id") or diag "Looks like this failed";
533 }; ## End of the eval function
535 if ($@) {
536 print "\nEVAL ERROR:\n\n$@\n";
541 ## RESTORING THE ORIGINAL STATE IN THE DATABASE
542 ## To restore the original state in the database, rollback (it is in a transaction) and set the table_sequence values.
544 $schema->txn_rollback();
546 ## The transaction change the values in the sequence, so if we want set the original value, before the changes
547 ## we have two options:
548 ## 1) SELECT setval (<sequence_name>, $last_value_before_change, true); that said, ok your last true value was...
549 ## 2) SELECT setval (<sequence_name>, $last_value_before_change+1, false); It is false that your last value was ... so the
550 ## next time take the value before this.
552 ## The option 1 leave the seq information in a original state except if there aren't any value in the seq, that it is
553 ## more as the option 2
555 if ($ENV{RESET_DBSEQ}) {
556 $schema->set_sqlseq_values_to_original_state(\%last_ids);