Merge pull request #5134 from solgenomics/topic/fix_seedlot_search
[sgn.git] / t / unit_fixture / CXGN / Uploading / UploadAndAddCrossesCrossingtrial.t
blob871ee71b14eb0dd344f74441dc76f4e6e14666e4
2 use strict;
3 use warnings;
5 use lib 't/lib';
6 use SGN::Test::Fixture;
7 use Test::More;
8 use Test::WWW::Mechanize;
9 use LWP::UserAgent;
10 use CXGN::Trial;
11 use CXGN::Pedigree::AddCrossingtrial;
12 use CXGN::Pedigree::AddCrosses;
13 use CXGN::Pedigree::AddCrossInfo;
14 use CXGN::Pedigree::AddProgeniesExistingAccessions;
15 use CXGN::Pedigree::AddPedigrees;
16 use Bio::GeneticRelationships::Individual;
17 use Bio::GeneticRelationships::Pedigree;
18 use CXGN::Cross;
19 use CXGN::Pedigree::AddCrossTissueSamples;
20 use LWP::UserAgent;
21 use CXGN::Trial::Download;
22 use Spreadsheet::WriteExcel;
23 use Spreadsheet::Read;
25 #Needed to update IO::Socket::SSL
26 use Data::Dumper;
27 use JSON;
28 local $Data::Dumper::Indent = 0;
30 my $f = SGN::Test::Fixture->new();
31 my $schema = $f->bcs_schema;
32 my $phenome_schema = $f->phenome_schema;
34 my $mech = Test::WWW::Mechanize->new;
36 for my $extension ("xls", "xlsx") {
38     # test adding crossing trial
39     $mech->post_ok('http://localhost:3010/brapi/v1/token', [ "username" => "janedoe", "password" => "secretpw", "grant_type" => "password" ]);
40     my $response = decode_json $mech->content;
41     is($response->{'metadata'}->{'status'}->[2]->{'message'}, 'Login Successfull');
42     my $sgn_session_id = $response->{access_token};
43     print STDERR $sgn_session_id . "\n";
45     $mech->post_ok('http://localhost:3010/ajax/cross/add_crossingtrial', [ 'crossingtrial_name' => 'test_crossingtrial', 'crossingtrial_program_id' => 134,
46         'crossingtrial_location'                                                                => 'test_location', 'year' => '2017', 'project_description' => 'test description' ]);
48     $response = decode_json $mech->content;
49     is($response->{'success'}, '1');
51     $mech->post_ok('http://localhost:3010/ajax/cross/add_crossingtrial', [ 'crossingtrial_name' => 'test_crossingtrial2', 'crossingtrial_program_id' => 134,
52         'crossingtrial_location'                                                                => 'test_location', 'year' => '2018', 'project_description' => 'test description2' ]);
54     $response = decode_json $mech->content;
55     is($response->{'success'}, '1');
57     $mech->post_ok('http://localhost:3010/ajax/cross/add_crossingtrial', [ 'crossingtrial_name' => 'test_crossingtrial_deletion', 'crossingtrial_program_id' => 134,
58         'crossingtrial_location'                                                                => 'test_location', 'year' => '2019', 'project_description' => 'test deletion' ]);
60     $response = decode_json $mech->content;
61     is($response->{'success'}, '1');
63     #create populations for testing bulk and bulk_open cross types
64     $mech->post_ok('http://localhost:3010/ajax/population/new', [ "population_name"=> 'test_population_A', "accessions[]"=> ['UG120001', 'UG120002'] ]);
65     $response = decode_json $mech->content;
66     is($response->{'success'}, "Success! Population test_population_A created");
67     my $population_A_id = $response->{'population_id'};
69     $mech->post_ok('http://localhost:3010/ajax/population/new', [ "population_name"=> 'test_population_B', "accessions[]"=> ['UG120003', 'UG120004'] ]);
70     $response = decode_json $mech->content;
71     is($response->{'success'}, "Success! Population test_population_B created");
72     my $population_B_id = $response->{'population_id'};
74     # test adding cross and info
75     my $crossing_trial_rs = $schema->resultset('Project::Project')->find({ name => 'test_crossingtrial' });
76     my $crossing_trial_id = $crossing_trial_rs->project_id();
77     my $female_plot_id = $schema->resultset('Stock::Stock')->find({ name => 'KASESE_TP2013_842' })->stock_id();
78     my $male_plot_id = $schema->resultset('Stock::Stock')->find({ name => 'KASESE_TP2013_1591' })->stock_id();
79     my $cross_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "cross", "stock_type")->cvterm_id();
80     my $cross_combination_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "cross_combination", "stock_property")->cvterm_id();
82     my $before_adding_cross = $schema->resultset("Stock::Stock")->search({ type_id => $cross_type_id })->count();
83     my $before_adding_stocks = $schema->resultset("Stock::Stock")->search({})->count();
84     my $before_adding_stockprop = $schema->resultset("Stock::Stockprop")->search({ type_id => $cross_combination_type_id })->count();
85     my $before_adding_stockprop_all = $schema->resultset("Stock::Stockprop")->search({})->count();
86     my $before_adding_relationship = $schema->resultset("Stock::StockRelationship")->search({})->count();
87     my $before_adding_cross_in_experiment = $schema->resultset("NaturalDiversity::NdExperiment")->search({})->count();
88     my $before_adding_cross_in_experiment_stock = $schema->resultset("NaturalDiversity::NdExperimentStock")->search({})->count();
90     $mech->post_ok('http://localhost:3010/ajax/cross/add_cross', [ 'crossing_trial_id' => $crossing_trial_id, 'cross_name' => 'test_add_cross', 'cross_combination' => 'UG120001xUG120002', 'cross_type' => 'biparental', 'maternal' => 'UG120001', 'paternal' => 'UG120002', 'female_plot' => $female_plot_id, 'male_plot' => $male_plot_id ]);
92     $response = decode_json $mech->content;
93     is($response->{'success'}, '1');
95     my $after_adding_cross = $schema->resultset("Stock::Stock")->search({ type_id => $cross_type_id })->count();
96     my $after_adding_stocks = $schema->resultset("Stock::Stock")->search({})->count();
97     my $after_adding_stockprop = $schema->resultset("Stock::Stockprop")->search({ type_id => $cross_combination_type_id })->count();
98     my $after_adding_stockprop_all = $schema->resultset("Stock::Stockprop")->search({})->count();
99     my $after_adding_relationship = $schema->resultset("Stock::StockRelationship")->search({})->count();
100     my $after_adding_cross_in_experiment = $schema->resultset("NaturalDiversity::NdExperiment")->search({})->count();
101     my $after_adding_cross_in_experiment_stock = $schema->resultset("NaturalDiversity::NdExperimentStock")->search({})->count();
103     is($after_adding_cross, $before_adding_cross + 1);
104     is($after_adding_stocks, $before_adding_stocks + 1);
105     is($after_adding_stockprop, $before_adding_stockprop + 1);
106     is($after_adding_stockprop_all, $before_adding_stockprop_all + 2);
107     is($after_adding_relationship, $before_adding_relationship + 4);
108     is($after_adding_cross_in_experiment, $before_adding_cross_in_experiment + 1);
109     is($after_adding_cross_in_experiment_stock, $before_adding_cross_in_experiment_stock + 1);
111     #test adding a cross with backcross cross type
112     my $crossing_trial2_rs = $schema->resultset('Project::Project')->find({ name => 'test_crossingtrial2' });
113     my $crossing_trial2_id = $crossing_trial2_rs->project_id();
115     $mech->post_ok('http://localhost:3010/ajax/cross/add_cross', [ 'crossing_trial_id' => $crossing_trial2_id, 'cross_name' => 'test_backcross1', 'cross_combination' => 'test_add_crossxUG120001', 'cross_type' => 'backcross', 'maternal' => 'test_add_cross', 'paternal' => 'UG120001' ]);
117     $response = decode_json $mech->content;
118     is($response->{'success'}, '1');
120     #test uploading crosses with backcross cross type
121     my $file = $f->config->{basepath} . "/t/data/cross/backcross_upload.$extension";
122     my $ua = LWP::UserAgent->new;
123     $response = $ua->post(
124         'http://localhost:3010/ajax/cross/upload_crosses_file',
125         Content_Type => 'form-data',
126         Content      => [
127             "xls_crosses_simple_file"               => [
128                 $file,
129                 "backcross_upload.$extension",
130                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
131             ],
132             "upload_crosses_crossing_experiment_id" => $crossing_trial2_id,
133             "sgn_session_id"                        => $sgn_session_id
134         ]
135     );
136     ok($response->is_success);
137     my $message = $response->decoded_content;
138     my $message_hash = decode_json $message;
139     is_deeply($message_hash, { 'success' => 1 });
141     # test uploading crosses with only accession info
143     my $before_uploading_cross_a = $schema->resultset("Stock::Stock")->search({ type_id => $cross_type_id })->count();
144     my $before_uploading_stocks_a = $schema->resultset("Stock::Stock")->search({})->count();
145     my $before_uploading_relationship_a = $schema->resultset("Stock::StockRelationship")->search({})->count();
147     my $file = $f->config->{basepath} . "/t/data/cross/crosses_simple_upload.$extension";
148     my $ua = LWP::UserAgent->new;
149     $response = $ua->post(
150         'http://localhost:3010/ajax/cross/upload_crosses_file',
151         Content_Type => 'form-data',
152         Content      => [
153             "xls_crosses_simple_file"               => [
154                 $file,
155                 "crosses_simple_upload.$extension",
156                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
157             ],
158             "upload_crosses_crossing_experiment_id" => $crossing_trial2_id,
159             "sgn_session_id"                        => $sgn_session_id
160         ]
161     );
162     ok($response->is_success);
163     my $message = $response->decoded_content;
164     my $message_hash = decode_json $message;
165     is_deeply($message_hash, { 'success' => 1 });
167     my $after_uploading_cross_a = $schema->resultset("Stock::Stock")->search({ type_id => $cross_type_id })->count();
168     my $after_uploading_stocks_a = $schema->resultset("Stock::Stock")->search({})->count();
169     my $after_uploading_relationship_a = $schema->resultset("Stock::StockRelationship")->search({})->count();
171     is($after_uploading_cross_a, $before_uploading_cross_a + 4);
172     is($after_uploading_stocks_a, $before_uploading_stocks_a + 4);
173     is($after_uploading_relationship_a, $before_uploading_relationship_a + 8);
175     # test uploading crosses with plots
176     my $female_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "female_parent", "stock_relationship")->cvterm_id();
177     my $male_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "male_parent", "stock_relationship")->cvterm_id();
178     my $female_plot_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "female_plot_of", "stock_relationship")->cvterm_id();
179     my $male_plot_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "male_plot_of", "stock_relationship")->cvterm_id();
181     my $before_uploading_relationship_all = $schema->resultset("Stock::StockRelationship")->search({})->count();
182     my $before_uploading_relationship_female = $schema->resultset("Stock::StockRelationship")->search({ type_id => $female_type_id })->count();
183     my $before_uploading_relationship_male = $schema->resultset("Stock::StockRelationship")->search({ type_id => $male_type_id })->count();
184     my $before_uploading_relationship_femaleplot = $schema->resultset("Stock::StockRelationship")->search({ type_id => $female_plot_type_id })->count();
185     my $before_uploading_relationship_maleplot = $schema->resultset("Stock::StockRelationship")->search({ type_id => $male_plot_type_id })->count();
187     $file = $f->config->{basepath} . "/t/data/cross/crosses_plots_upload.$extension";
188     $ua = LWP::UserAgent->new;
189     $response = $ua->post(
190         'http://localhost:3010/ajax/cross/upload_crosses_file',
191         Content_Type => 'form-data',
192         Content      => [
193             "xls_crosses_plots_file"                => [
194                 $file,
195                 "crosses_plots_upload.$extension",
196                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
197             ],
198             "upload_crosses_crossing_experiment_id" => $crossing_trial2_id,
199             "sgn_session_id"                        => $sgn_session_id
200         ]
201     );
202     ok($response->is_success);
203     $message = $response->decoded_content;
204     $message_hash = decode_json $message;
205     is_deeply($message_hash, { 'success' => 1 });
207     my $after_uploading_relationship_all = $schema->resultset("Stock::StockRelationship")->search({})->count();
208     my $after_uploading_relationship_female = $schema->resultset("Stock::StockRelationship")->search({ type_id => $female_type_id })->count();
209     my $after_uploading_relationship_male = $schema->resultset("Stock::StockRelationship")->search({ type_id => $male_type_id })->count();
210     my $after_uploading_relationship_femaleplot = $schema->resultset("Stock::StockRelationship")->search({ type_id => $female_plot_type_id })->count();
211     my $after_uploading_relationship_maleplot = $schema->resultset("Stock::StockRelationship")->search({ type_id => $male_plot_type_id })->count();
213     is($after_uploading_relationship_all, $before_uploading_relationship_all + 8);
214     is($after_uploading_relationship_female, $before_uploading_relationship_female + 2);
215     is($after_uploading_relationship_male, $before_uploading_relationship_male + 2);
216     is($after_uploading_relationship_femaleplot, $before_uploading_relationship_femaleplot + 2);
217     is($after_uploading_relationship_maleplot, $before_uploading_relationship_maleplot + 2);
219     #add plants for testing (a total of 38 entries)
220     my $trial = CXGN::Trial->new({ bcs_schema => $schema, trial_id => 165 });
221     $trial->create_plant_entities(2);
223     # test uploading crosses with plants
224     my $female_plant_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "female_parent", "stock_relationship")->cvterm_id();
225     my $male_plant_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "male_parent", "stock_relationship")->cvterm_id();
227     my $before_uploading_relationship_femaleplant = $schema->resultset("Stock::StockRelationship")->search({ type_id => $female_plant_type_id })->count();
228     my $before_uploading_relationship_maleplant = $schema->resultset("Stock::StockRelationship")->search({ type_id => $male_plant_type_id })->count();
230     $file = $f->config->{basepath} . "/t/data/cross/crosses_plants_upload.$extension";
231     $ua = LWP::UserAgent->new;
232     $response = $ua->post(
233         'http://localhost:3010/ajax/cross/upload_crosses_file',
234         Content_Type => 'form-data',
235         Content      => [
236             "xls_crosses_plants_file"               => [
237                 $file,
238                 "crosses_plants_upload.$extension",
239                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
240             ],
241             "upload_crosses_crossing_experiment_id" => $crossing_trial2_id,
242             "sgn_session_id"                        => $sgn_session_id
243         ]
244     );
245     ok($response->is_success);
246     $message = $response->decoded_content;
247     $message_hash = decode_json $message;
248     is_deeply($message_hash, { 'success' => 1 });
250     my $after_uploading_relationship_femaleplant = $schema->resultset("Stock::StockRelationship")->search({ type_id => $female_plant_type_id })->count();
251     my $after_uploading_relationship_maleplant = $schema->resultset("Stock::StockRelationship")->search({ type_id => $male_plant_type_id })->count();
253     is($after_uploading_relationship_femaleplant, $before_uploading_relationship_femaleplant + 2);
254     is($after_uploading_relationship_maleplant, $before_uploading_relationship_maleplant + 2);
256     # test uploading crosses with simplified parent info format
257     my $before_uploading_cross_simplified_info = $schema->resultset("Stock::Stock")->search({ type_id => $cross_type_id })->count();
258     my $before_uploading_stocks_simplified_info = $schema->resultset("Stock::Stock")->search({})->count();
259     my $before_uploading_relationship_simplified_info = $schema->resultset("Stock::StockRelationship")->search({})->count();
261     my $file = $f->config->{basepath} . "/t/data/cross/crosses_simplified_parents_upload.$extension";
262     my $ua = LWP::UserAgent->new;
263     $response = $ua->post(
264         'http://localhost:3010/ajax/cross/upload_crosses_file',
265         Content_Type => 'form-data',
266         Content      => [
267             "xls_crosses_simplified_parents_file" => [
268                 $file,
269                 "crosses_simplified_parents_upload.$extension",
270                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
271             ],
272             "upload_crosses_crossing_experiment_id" => $crossing_trial2_id,
273             "sgn_session_id"                        => $sgn_session_id
274         ]
275     );
276     ok($response->is_success);
277     my $message = $response->decoded_content;
278     my $message_hash = decode_json $message;
279     is_deeply($message_hash, { 'success' => 1 });
281     my $after_uploading_cross_simplified_info = $schema->resultset("Stock::Stock")->search({ type_id => $cross_type_id })->count();
282     my $after_uploading_stocks_simplified_info = $schema->resultset("Stock::Stock")->search({})->count();
283     my $after_uploading_relationship_simplified_info = $schema->resultset("Stock::StockRelationship")->search({})->count();
285     is($after_uploading_cross_simplified_info, $before_uploading_cross_simplified_info + 4);
286     is($after_uploading_stocks_simplified_info, $before_uploading_stocks_simplified_info + 4);
287     is($after_uploading_relationship_simplified_info, $before_uploading_relationship_simplified_info + 13);
289     # test retrieving crosses in a trial
290     my $test_add_cross_rs = $schema->resultset('Stock::Stock')->find({ name => 'test_add_cross' });
291     my $test_add_cross_id = $test_add_cross_rs->stock_id();
292     my $UG120001_id = $schema->resultset('Stock::Stock')->find({ name => 'UG120001' })->stock_id();
293     my $UG120002_id = $schema->resultset('Stock::Stock')->find({ name => 'UG120002' })->stock_id();
295     $mech->post_ok("http://localhost:3010/ajax/breeders/trial/$crossing_trial_id/crosses_and_details_in_trial");
296     $response = decode_json $mech->content;
298     is_deeply($response, { 'data' => [ {
299         cross_id            => $test_add_cross_id,
300         cross_name          => 'test_add_cross',
301         cross_combination   => 'UG120001xUG120002',
302         cross_type          => 'biparental',
303         female_parent_id    => $UG120001_id,
304         female_parent_name  => 'UG120001',
305         female_ploidy_level => undef,
306         male_parent_id      => $UG120002_id,
307         male_parent_name    => 'UG120002',
308         male_ploidy_level   => undef,
309         female_plot_id      => $female_plot_id,
310         female_plot_name    => 'KASESE_TP2013_842',
311         male_plot_id        => $male_plot_id,
312         male_plot_name      => 'KASESE_TP2013_1591',
313         female_plant_id     => undef,
314         female_plant_name   => undef,
315         male_plant_id       => undef,
316         male_plant_name     => undef
317     } ] }, 'crosses in a trial');
319     # test uploading 6 progenies with new accessions
320     my $offspring_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "offspring_of", "stock_relationship")->cvterm_id();
321     my $accession_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "accession", "stock_type")->cvterm_id();
323     my $before_add_progenies_stock = $schema->resultset("Stock::Stock")->search({})->count();
324     my $before_add_progenies_accession = $schema->resultset("Stock::Stock")->search({ type_id => $accession_type_id })->count();
325     my $before_add_progenies_relationship_all = $schema->resultset("Stock::StockRelationship")->search({})->count();
326     my $before_add_progenies_offspring = $schema->resultset("Stock::StockRelationship")->search({ type_id => $offspring_type_id })->count();
328     $file = $f->config->{basepath} . "/t/data/cross/update_progenies.$extension";
329     $ua = LWP::UserAgent->new;
330     $response = $ua->post(
331         'http://localhost:3010/ajax/cross/upload_progenies',
332         Content_Type => 'form-data',
333         Content      => [
334             progenies_new_upload_file => [
335                 $file,
336                 "update_progenies.$extension",
337                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
338             ],
339             "sgn_session_id"          => $sgn_session_id
340         ]
341     );
342     ok($response->is_success);
343     $message = $response->decoded_content;
344     $message_hash = decode_json $message;
345     is_deeply($message_hash, { 'success' => 1 });
347     my $after_add_progenies_stock = $schema->resultset("Stock::Stock")->search({})->count();
348     my $after_add_progenies_accession = $schema->resultset("Stock::Stock")->search({ type_id => $accession_type_id })->count();
349     my $after_add_progenies_relationship_all = $schema->resultset("Stock::StockRelationship")->search({})->count();
350     my $after_add_progenies_offspring = $schema->resultset("Stock::StockRelationship")->search({ type_id => $offspring_type_id })->count();
352     is($after_add_progenies_stock, $before_add_progenies_stock + 6);
353     is($after_add_progenies_accession, $before_add_progenies_accession + 6);
354     is($after_add_progenies_relationship_all, $before_add_progenies_relationship_all + 18);
355     is($after_add_progenies_offspring, $before_add_progenies_offspring + 6);
358     #validate uploading 4 progenies using existing accessions (without previously stored pedigrees)
359     $file = $f->config->{basepath} . "/t/data/cross/update_progenies_existing_accessions.$extension";
360     $ua = LWP::UserAgent->new;
361     $response = $ua->post(
362         'http://localhost:3010/ajax/cross/validate_upload_existing_progenies',
363         Content_Type => 'form-data',
364         Content      => [
365             progenies_exist_upload_file => [
366                 $file,
367                 "update_progenies_existing_accessions.$extension",
368                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
369             ],
370             "sgn_session_id"            => $sgn_session_id
371         ]
372     );
374     ok($response->is_success);
375     $message = $response->decoded_content;
376     $message_hash = decode_json $message;
377     my %response_hash = %$message_hash;
378     my $message1 = $response_hash{'error_string'};
379     my $message2 = $response_hash{'existing_pedigrees'};
380     ok($message1 eq '');
381     ok($message2 eq '');
384     #test storing 4 progenies using existing accessions (without previously stored pedigrees)
385     my $cross_name = 'test_add_cross';
386     my @existing_accessions = qw(XG120015 XG120021 XG120068 XG120073);
387     my $overwrite_pedigrees = 'true';
388     my $adding_progenies = CXGN::Pedigree::AddProgeniesExistingAccessions->new({
389         chado_schema  => $schema,
390         cross_name    => $cross_name,
391         progeny_names => \@existing_accessions,
392     });
394     ok(my $return = $adding_progenies->add_progenies_existing_accessions($overwrite_pedigrees));
395     ok(!exists($return->{error}));
397     my $after_add_progenies_exist_stock = $schema->resultset("Stock::Stock")->search({})->count();
398     my $after_add_progenies_exist_accession = $schema->resultset("Stock::Stock")->search({ type_id => $accession_type_id })->count();
399     my $after_add_progenies_exist_relationship_all = $schema->resultset("Stock::StockRelationship")->search({})->count();
400     my $after_add_progenies_exist_offspring = $schema->resultset("Stock::StockRelationship")->search({ type_id => $offspring_type_id })->count();
402     is($after_add_progenies_exist_stock, $after_add_progenies_stock);
403     is($after_add_progenies_exist_accession, $after_add_progenies_accession);
404     is($after_add_progenies_exist_relationship_all, $after_add_progenies_relationship_all + 12);
405     is($after_add_progenies_exist_offspring, $after_add_progenies_offspring + 4);
408     #validate uploading 2 progenies using existing accessions (accessions have previously stored pedigrees)
409     #adding pedigrees for testing
410     my $female_parent = Bio::GeneticRelationships::Individual->new(name => 'TestAccession1');
411     my $male_parent = Bio::GeneticRelationships::Individual->new(name => 'TestAccession2');
412     my $pedigree1 = Bio::GeneticRelationships::Pedigree->new(name => 'TestAccession3', cross_type => 'biparental');
413     $pedigree1->set_female_parent($female_parent);
414     $pedigree1->set_male_parent($male_parent);
416     my $pedigree2 = Bio::GeneticRelationships::Pedigree->new(name => 'TestAccession4', cross_type => 'biparental');
417     $pedigree2->set_female_parent($female_parent);
418     $pedigree2->set_male_parent($male_parent);
420     my @pedigrees = ($pedigree1, $pedigree2);
421     my $add_pedigrees = CXGN::Pedigree::AddPedigrees->new(schema => $schema, pedigrees => \@pedigrees);
422     my $pedigree_return = $add_pedigrees->add_pedigrees();
424     my $after_add_pedigrees_relationship_all = $schema->resultset("Stock::StockRelationship")->search({})->count();
426     $file = $f->config->{basepath} . "/t/data/cross/update_progenies_overwrite_pedigrees.$extension";
427     $ua = LWP::UserAgent->new;
428     $response = $ua->post(
429         'http://localhost:3010/ajax/cross/validate_upload_existing_progenies',
430         Content_Type => 'form-data',
431         Content      => [
432             progenies_exist_upload_file => [
433                 $file,
434                 "update_progenies_overwrite_pedigrees.$extension",
435                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
436             ],
437             "sgn_session_id"            => $sgn_session_id
438         ]
439     );
441     ok($response->is_success);
442     $message = $response->decoded_content;
443     $message_hash = decode_json $message;
444     %response_hash = %$message_hash;
445     my $message3 = $response_hash{'error_string'};
446     my $message4 = $response_hash{'existing_pedigrees'};
447     ok($message3 eq '');
448     ok($message4 ne '');
451     #test storing 2 progenies using existing accessions (accessions have previously stored pedigrees)
452     $cross_name = 'test_add_cross';
453     @existing_accessions = qw(TestAccession3 TestAccession4);
454     $overwrite_pedigrees = 'true';
455     $adding_progenies = CXGN::Pedigree::AddProgeniesExistingAccessions->new({
456         chado_schema  => $schema,
457         cross_name    => $cross_name,
458         progeny_names => \@existing_accessions,
459     });
461     ok($return = $adding_progenies->add_progenies_existing_accessions($overwrite_pedigrees));
462     ok(!exists($return->{error}));
464     my $after_add_progenies_overwrite_stock = $schema->resultset("Stock::Stock")->search({})->count();
465     my $after_add_progenies_overwrite_accession = $schema->resultset("Stock::Stock")->search({ type_id => $accession_type_id })->count();
466     my $after_add_progenies_overwrite_relationship_all = $schema->resultset("Stock::StockRelationship")->search({})->count();
467     my $after_add_progenies_overwrite_offspring = $schema->resultset("Stock::StockRelationship")->search({ type_id => $offspring_type_id })->count();
469     is($after_add_progenies_overwrite_stock, $after_add_progenies_exist_stock);
470     is($after_add_progenies_overwrite_accession, $after_add_progenies_exist_accession);
471     is($after_add_progenies_overwrite_relationship_all, $after_add_pedigrees_relationship_all + 2);
472     is($after_add_progenies_overwrite_offspring, $after_add_progenies_exist_offspring + 2);
475     # test updating cross info by uploading
476     my $before_updating_info_stocks = $schema->resultset("Stock::Stock")->search({})->count();
477     my $before_updating_info_stockprop = $schema->resultset("Stock::Stockprop")->search({})->count();
478     my $before_updating_info_relationship = $schema->resultset("Stock::StockRelationship")->search({})->count();
480     $file = $f->config->{basepath} . "/t/data/cross/update_crossinfo.$extension";
481     $ua = LWP::UserAgent->new;
482     $response = $ua->post(
483         'http://localhost:3010/ajax/cross/upload_info',
484         Content_Type => 'form-data',
485         Content      => [
486             crossinfo_upload_file => [
487                 $file,
488                 "update_crossinfo.$extension",
489                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
490             ],
491             "sgn_session_id"      => $sgn_session_id
492         ]
493     );
494     ok($response->is_success);
495     $message = $response->decoded_content;
496     $message_hash = decode_json $message;
497     is_deeply($message_hash, { 'success' => 1 });
499     my $after_updating_info_stocks = $schema->resultset("Stock::Stock")->search({})->count();
500     my $after_updating_info_stockprop = $schema->resultset("Stock::Stockprop")->search({})->count();
501     my $after_updating_info_relationship = $schema->resultset("Stock::StockRelationship")->search({})->count();
503     is($after_updating_info_stocks, $before_updating_info_stocks);
504     is($after_updating_info_stockprop, $before_updating_info_stockprop + 3);
505     is($after_updating_info_relationship, $before_updating_info_relationship);
507     # test uploading additional parent info
508     $file = $f->config->{basepath} . "/t/data/cross/upload_additional_info.$extension";
509     $ua = LWP::UserAgent->new;
510     $response = $ua->post(
511         'http://localhost:3010/ajax/cross/upload_info',
512         Content_Type => 'form-data',
513         Content      => [
514             additional_info_upload_file => [
515                 $file,
516                 "upload_additional_info.$extension",
517                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
518             ],
519             "sgn_session_id"            => $sgn_session_id
520         ]
521     );
522     ok($response->is_success);
523     $message = $response->decoded_content;
524     $message_hash = decode_json $message;
525     is_deeply($message_hash, { 'success' => 1 });
527     my $after_upload_additional_info_stocks = $schema->resultset("Stock::Stock")->search({})->count();
528     my $after_upload_additional_info_stockprop = $schema->resultset("Stock::Stockprop")->search({})->count();
529     my $after_upload_additional_info_relationship = $schema->resultset("Stock::StockRelationship")->search({})->count();
531     # note:added 3 more rows in stockprop table after uploading field crossing activities, then 3 more rows in stockprop table after uploading parent additional info
532     is($after_upload_additional_info_stocks, $before_updating_info_stocks);
533     is($after_upload_additional_info_stockprop, $before_updating_info_stockprop + 6);
534     is($after_upload_additional_info_relationship, $before_updating_info_relationship);
536     # test retrieving crossing experimental info after updating
537     $mech->post_ok("http://localhost:3010/ajax/breeders/trial/$crossing_trial_id/cross_properties_trial");
538     $response = decode_json $mech->content;
540     is_deeply($response, { 'data' => [
541         [ qq{<a href = "/cross/$test_add_cross_id">test_add_cross</a>}, 'UG120001xUG120002', "10", "2017/02/02", "10", "50", undef, undef ]
542     ] }, 'crossing experiment info');
545     # test uploading family names
546     my $family_name_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "family_name", "stock_type")->cvterm_id();
547     my $cross_member_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'cross_member_of', 'stock_relationship')->cvterm_id();
548     my $family_female_parent_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'family_female_parent_of', 'stock_relationship')->cvterm_id();
549     my $family_male_parent_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'family_male_parent_of', 'stock_relationship')->cvterm_id();
550     my $family_type_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, "family_type", "stock_property")->cvterm_id();
552     my $before_family_name_stocks = $schema->resultset("Stock::Stock")->search({})->count();
553     my $before_add_family_name = $schema->resultset("Stock::Stock")->search({ type_id => $family_name_type_id })->count();
554     my $before_upload_family_relationship = $schema->resultset("Stock::StockRelationship")->search({})->count();
555     my $before_upload_family_member = $schema->resultset("Stock::StockRelationship")->search({ type_id => $cross_member_of_cvterm_id })->count();
556     my $before_upload_family_female = $schema->resultset("Stock::StockRelationship")->search({ type_id => $family_female_parent_cvterm_id })->count();
557     my $before_upload_family_male = $schema->resultset("Stock::StockRelationship")->search({ type_id => $family_male_parent_cvterm_id })->count();
558     my $before_upload_family_stockprop = $schema->resultset("Stock::Stockprop")->search({ type_id => $family_type_cvterm_id })->count();
560     $file = $f->config->{basepath} . "/t/data/cross/family_name_upload.$extension";
561     $ua = LWP::UserAgent->new;
562     $response = $ua->post(
563         'http://localhost:3010/ajax/cross/upload_family_names',
564         Content_Type => 'form-data',
565         Content      => [
566             same_parents_file => [
567                 $file,
568                 "family_name_upload.$extension",
569                 Content_Type => ($extension eq "xls") ? 'application/vnd.ms-excel' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
570             ],
571             "sgn_session_id"  => $sgn_session_id
572         ]
573     );
574     ok($response->is_success);
575     $message = $response->decoded_content;
576     $message_hash = decode_json $message;
577     is_deeply($message_hash, { 'success' => 1 });
579     my $after_family_name_stocks = $schema->resultset("Stock::Stock")->search({})->count();
580     my $after_add_family_name = $schema->resultset("Stock::Stock")->search({ type_id => $family_name_type_id })->count();
581     my $after_upload_family_relationship = $schema->resultset("Stock::StockRelationship")->search({})->count();
582     my $after_upload_family_member = $schema->resultset("Stock::StockRelationship")->search({ type_id => $cross_member_of_cvterm_id })->count();
583     my $after_upload_family_female = $schema->resultset("Stock::StockRelationship")->search({ type_id => $family_female_parent_cvterm_id })->count();
584     my $after_upload_family_male = $schema->resultset("Stock::StockRelationship")->search({ type_id => $family_male_parent_cvterm_id })->count();
585     my $after_upload_family_stockprop = $schema->resultset("Stock::Stockprop")->search({ type_id => $family_type_cvterm_id })->count();
587     is($after_family_name_stocks, $before_family_name_stocks + 2);
588     is($after_add_family_name, $before_add_family_name + 2);
589     is($after_upload_family_relationship, $before_upload_family_relationship + 8);
590     is($after_upload_family_member, $before_upload_family_member + 4);
591     is($after_upload_family_female, $before_upload_family_female + 2);
592     is($after_upload_family_male, $before_upload_family_male + 2);
593     is($after_upload_family_stockprop, $before_upload_family_stockprop + 2);
595     #test retrieving family name info
596     my $family_stock_rs = $schema->resultset("Stock::Stock")->find({ name => 'family1x2', type_id => $family_name_type_id });
597     my $family_stock_id = $family_stock_rs->stock_id();
598     my $family_type = $schema->resultset("Stock::Stockprop")->find({ stock_id => $family_stock_id, type_id => $family_type_cvterm_id })->value();
599     is($family_type, 'same_parents');
600     #print STDERR "FAMILY ID =".Dumper($family_stock_id)."\n";
601     $mech->post_ok('http://localhost:3010/ajax/family/members/' . $family_stock_id);
602     $response = decode_json $mech->content;
603     my %data = %$response;
604     my $members = $data{data};
605     my $number_of_members = @$members;
606     is($number_of_members, 2);
608     $mech->post_ok('http://localhost:3010/ajax/family/all_progenies/' . $family_stock_id);
609     $response = decode_json $mech->content;
610     my %data = %$response;
611     my $progenies = $data{data};
612     my $number_of_progenies = @$progenies;
613     is($number_of_progenies, 2);
615     #test adding tissue culture samples
616     my $before_adding_samples_stockprop = $schema->resultset("Stock::Stockprop")->search({})->count();
618     my $cross_unique_id = 'test_add_cross';
619     my $sample_type = 'Embryo IDs';
620     my @ids = qw(test_embryo_1 test_embryo_2 test_embryo_3 test_embryo_4);
621     my $cross_add_samples = CXGN::Pedigree::AddCrossTissueSamples->new({
622         chado_schema => $schema,
623         cross_name   => $cross_unique_id,
624         key          => $sample_type,
625         value        => \@ids,
626     });
628     ok(my $return = $cross_add_samples->add_samples());
630     my $after_adding_samples_stockprop = $schema->resultset("Stock::Stockprop")->search({})->count();
631     is($after_adding_samples_stockprop, $before_adding_samples_stockprop + 1);
633     #test retrieving tissue culture samples
634     my $cross_id = $schema->resultset('Stock::Stock')->find({ name => 'test_add_cross' })->stock_id();
635     my $cross_samples_obj = CXGN::Cross->new({ schema => $schema, cross_stock_id => $cross_id });
636     my $cross_sample_data = $cross_samples_obj->get_cross_tissue_culture_samples();
637     my $embryo_ids_ref = $cross_sample_data->{'Embryo IDs'};
638     my $number_of_embryo_samples = @$embryo_ids_ref;
639     is($number_of_embryo_samples, 4);
642     #test search crosses using female parent
643     $mech->post_ok('http://localhost:3010/ajax/search/crosses', [ 'female_parent' => 'TMEB419' ]);
644     $response = decode_json $mech->content;
645     my %data1 = %$response;
646     my $result1 = $data1{data};
647     my $number_of_result1 = @$result1;
648     is($number_of_result1, 3);
650     #test search crosses using both female and male parents
651     $mech->post_ok('http://localhost:3010/ajax/search/crosses', [ 'female_parent' => 'TMEB419', 'male_parent' => 'TMEB693' ]);
652     $response = decode_json $mech->content;
653     my %data2 = %$response;
654     my $result2 = $data2{data};
655     my $number_of_result2 = @$result2;
656     is($number_of_result2, 2);
658     #test search crosses using male parent
659     $mech->post_ok('http://localhost:3010/ajax/search/crosses', [ 'male_parent' => 'TMEB693' ]);
660     $response = decode_json $mech->content;
661     my %data3 = %$response;
662     my $result3 = $data3{data};
663     my $number_of_result3 = @$result3;
664     is($number_of_result3, 2);
666     #test crossing experiment download
667     my @cross_properties = ("Tag Number", "Pollination Date", "Number of Bags", "Number of Flowers", "Number of Fruits", "Number of Seeds");
668     my $tempfile = "/tmp/test_download_crossing_experiment.$extension";
669     my $format = 'CrossingExperimentXLS';
670     my $create_spreadsheet = CXGN::Trial::Download->new({
671         bcs_schema                => $f->bcs_schema,
672         trial_list                => [ $crossing_trial2_id ],
673         filename                  => $tempfile,
674         format                    => $format,
675         field_crossing_data_order => \@cross_properties
676     });
678     $create_spreadsheet->download();
679     my $contents = ReadData $tempfile;
681     my $columns = $contents->[1]->{'cell'};
682     my @column_array = @$columns;
683     my $number_of_columns = scalar @column_array;
684     print STDERR "COLUMNS =".Dumper ($columns)."\n";
686     ok(scalar($number_of_columns) == 22, "check number of columns.");
687     is_deeply($contents->[1]->{'cell'}->[1], [
688         undef,
689         'Cross Unique ID',
690         'test_backcross1',
691         'test_backcross2',
692         'test_backcross3',
693         'test_cross_upload1',
694         'test_cross_upload2',
695         'test_bulk_cross',
696         'test_bulk_open_cross',
697         'test_cross_upload3',
698         'test_cross_upload4',
699         'test_cross_upload5',
700         'test_cross_upload6',
701         'test_cross_simplified_parents_1',
702         'test_cross_simplified_parents_2',
703         'test_cross_simplified_parents_3',
704         'test_cross_simplified_parents_4'
705     ], "check column 1");
707     is_deeply($contents->[1]->{'cell'}->[3], [
708         undef,
709         'Cross Type',
710         'backcross',
711         'backcross',
712         'backcross',
713         'biparental',
714         'self',
715         'bulk',
716         'bulk_open',
717         'biparental',
718         'self',
719         'biparental',
720         'self',
721         'biparental',
722         'biparental',
723         'biparental',
724         'biparental'
725     ], "check column 3");
727     is_deeply($contents->[1]->{'cell'}->[4], [
728         undef,
729         'Female Parent',
730         'test_add_cross',
731         'test_add_cross',
732         'test_add_cross',
733         'UG120001',
734         'UG120001',
735         'test_population_A',
736         'test_population_A',
737         'UG120001',
738         'UG120001',
739         'TMEB419',
740         'TMEB419',
741         'UG120001',
742         'UG120001',
743         'UG120001',
744         'TMEB419'
745     ], "check column 4");
748     # test retrieving all cross entries
749     my $crosses = CXGN::Cross->new({ schema => $schema });
750     my $result = $crosses->get_all_cross_entries();
751     my @all_cross_entries = @$result;
752     my $first_cross = $all_cross_entries[0];
753     is(scalar @all_cross_entries, 16);
754     is($first_cross->[1], 'test_add_cross');
755     is($first_cross->[2], 'biparental');
756     is($first_cross->[4], 'UG120001');
757     is($first_cross->[8], 'UG120002');
758     is($first_cross->[11], '2017/02/02');
759     is($first_cross->[13], 8);
760     is($first_cross->[15], 'test_crossingtrial');
762     #test deleting cross
763     my $before_deleting_crosses = $schema->resultset("Stock::Stock")->search({ type_id => $cross_type_id })->count();
764     my $before_deleting_accessions = $schema->resultset("Stock::Stock")->search({ type_id => $accession_type_id })->count();
765     my $before_deleting_stocks = $schema->resultset("Stock::Stock")->search({})->count();
766     my $before_deleting_relationship = $schema->resultset("Stock::StockRelationship")->search({})->count();
767     my $experiment_before_deleting_cross = $schema->resultset("NaturalDiversity::NdExperiment")->search({})->count();
768     my $experiment_stock_before_deleting_cross = $schema->resultset("NaturalDiversity::NdExperimentStock")->search({})->count();
770     # test_cross_upload1 has 2 progenies and has family name
771     my $deleting_cross_id = $schema->resultset("Stock::Stock")->find({ name => 'test_cross_upload1' })->stock_id;
772     $mech->post_ok('http://localhost:3010/ajax/cross/delete', [ 'cross_id' => $deleting_cross_id ]);
773     $response = decode_json $mech->content;
774     is($response->{'success'}, '1');
776     my $after_deleting_crosses = $schema->resultset("Stock::Stock")->search({ type_id => $cross_type_id })->count();
777     my $after_deleting_accessions = $schema->resultset("Stock::Stock")->search({ type_id => $accession_type_id })->count();
778     my $after_deleting_stocks = $schema->resultset("Stock::Stock")->search({})->count();
779     my $after_deleting_relationship = $schema->resultset("Stock::StockRelationship")->search({})->count();
780     my $experiment_after_deleting_cross = $schema->resultset("NaturalDiversity::NdExperiment")->search({})->count();
781     my $experiment_stock_after_deleting_cross = $schema->resultset("NaturalDiversity::NdExperimentStock")->search({})->count();
783     is($after_deleting_crosses, $before_deleting_crosses - 1);
784     is($after_deleting_accessions, $before_deleting_accessions - 2);
785     is($after_deleting_stocks, $before_deleting_stocks - 3);
786     is($after_deleting_relationship, $before_deleting_relationship - 9);
787     is($experiment_after_deleting_cross, $experiment_before_deleting_cross - 1);
788     is($experiment_stock_after_deleting_cross, $experiment_stock_before_deleting_cross - 1);
790     # test deleting empty crossing experiment
791     my $before_deleting_empty_experiment = $schema->resultset("Project::Project")->search({})->count();
793     my $crossing_experiment_id = $schema->resultset("Project::Project")->find({ name => 'test_crossingtrial_deletion' })->project_id;
794     $mech->get_ok('http://localhost:3010/ajax/breeders/trial/' . $crossing_experiment_id . '/delete/crossing_experiment');
795     $response = decode_json $mech->content;
796     is($response->{'success'}, '1');
798     my $after_deleting_empty_experiment = $schema->resultset("Project::Project")->search({})->count();
800     is($after_deleting_empty_experiment, $before_deleting_empty_experiment - 1);
802     # test deleting crossing experiment with crosses
803     my $before_deleting_experiment = $schema->resultset("Project::Project")->search({})->count();
805     my $crossing_experiment_id_2 = $schema->resultset("Project::Project")->find({ name => 'test_crossingtrial' })->project_id;
806     $mech->get_ok('http://localhost:3010/ajax/breeders/trial/' . $crossing_experiment_id_2 . '/delete/crossing_experiment');
807     $response = decode_json $mech->content;
808     ok($response->{'error'});
810     my $after_deleting_experiment = $schema->resultset("Project::Project")->search({})->count();
812     is($after_deleting_experiment, $before_deleting_experiment);
814     #test deleting all crosses in test_crossingtrial and test_crossingtrial2
815     $mech->get_ok('http://localhost:3010/ajax/breeders/trial/' . $crossing_trial2_id . '/delete_all_crosses_in_crossingtrial');
816     $mech->get_ok('http://localhost:3010/ajax/breeders/trial/' . $crossing_trial_id . '/delete_all_crosses_in_crossingtrial');
818     my $after_delete_all_crosses = $schema->resultset("Stock::Stock")->search({ type_id => $cross_type_id })->count();
819     my $after_delete_all_crosses_in_experiment = $schema->resultset("NaturalDiversity::NdExperiment")->search({})->count();
820     my $after_delete_all_crosses_in_experiment_stock = $schema->resultset("NaturalDiversity::NdExperimentStock")->search({})->count();
821     my $stocks_after_delete_all_crosses = $schema->resultset("Stock::Stock")->search({})->count();
823     is($after_delete_all_crosses, $before_adding_cross + 1);                             #one cross cannot be deleted because progenies have associated data
824     is($after_delete_all_crosses_in_experiment, $before_adding_cross_in_experiment + 1); #one cross cannot be deleted because progenies have associated data
826     # nd_experiment_stock has 38 more rows after adding plants for testing uploading crosses with plant info
827     is($after_delete_all_crosses_in_experiment_stock, $before_adding_cross_in_experiment_stock + 39);
829     # stock table has 43 more rows after adding family names and plants, one cross with two new accessions cannot be deleted
830     is($stocks_after_delete_all_crosses, $before_adding_stocks + 43);
832     # remove added crossing trials after test so that they don't affect downstream tests
833     my $project_owner_row_1 = $phenome_schema->resultset('ProjectOwner')->find({ project_id => $crossing_trial_rs->project_id() });
834     $project_owner_row_1->delete();
835     $crossing_trial_rs->delete();
837     my $project_owner_row_2 = $phenome_schema->resultset('ProjectOwner')->find({ project_id => $crossing_trial2_rs->project_id() });
838     $project_owner_row_2->delete();
839     $crossing_trial2_rs->delete();
841     $f->clean_up_db();
844 done_testing();