Merge pull request #5191 from solgenomics/topic/quality_control
[sgn.git] / t / unit_fixture / CXGN / Trial / TrialForCrossesFamilyNames.t
blob133ecf42f432eb5c0a9d119fab4588fc4a5638b4
2 use strict;
4 use Test::More;
5 use lib 't/lib';
6 use SGN::Test::Fixture;
7 use JSON::Any;
8 use Data::Dumper;
9 use Spreadsheet::WriteExcel;
10 use Spreadsheet::Read;
11 use Test::WWW::Mechanize;
12 use CXGN::Cross;
13 use JSON;
14 use LWP::UserAgent;
16 my $fix = SGN::Test::Fixture->new();
18 for my $extension ("xls", "xlsx") {
20     is(ref($fix->config()), "HASH", 'hashref check');
22     BEGIN {use_ok('CXGN::Trial::TrialCreate');}
23     BEGIN {use_ok('CXGN::Trial::TrialLayout');}
24     BEGIN {use_ok('CXGN::Trial::TrialDesign');}
25     BEGIN {use_ok('CXGN::Trial::TrialLookup');}
26     BEGIN {use_ok('CXGN::Trial::Download');}
27     BEGIN {use_ok('CXGN::Fieldbook::DownloadTrial');}
28     BEGIN {use_ok('CXGN::Trial::TrialLayoutDownload');}
29     BEGIN {use_ok('CXGN::Trial');}
31     ok(my $schema = $fix->bcs_schema);
32     ok(my $phenome_schema = $fix->phenome_schema);
33     ok(my $metadata_schema = $fix->metadata_schema);
34     ok(my $dbh = $fix->dbh);
37     # create crosses and family_names for trials
38     my $cross_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "cross", "stock_type")->cvterm_id();
39     my $family_name_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "family_name", "stock_type")->cvterm_id();
41     my @cross_ids;
42     for (my $i = 1; $i <= 5; $i++) {
43         push(@cross_ids, "cross_for_trial" . $i);
44     }
46     my @family_names;
47     for (my $i = 1; $i <= 5; $i++) {
48         push(@family_names, "family_name_for_trial" . $i);
49     }
51     ok(my $organism = $schema->resultset("Organism::Organism")
52         ->find_or_create({
53         genus   => 'Test_genus',
54         species => 'Test_genus test_species',
55     },));
57     foreach my $cross_id (@cross_ids) {
58         my $cross_for_trial = $schema->resultset('Stock::Stock')
59             ->create({
60             organism_id => $organism->organism_id,
61             name        => $cross_id,
62             uniquename  => $cross_id,
63             type_id     => $cross_type_id,
64         });
65     };
67     foreach my $family_name (@family_names) {
68         my $family_name_for_trial = $schema->resultset('Stock::Stock')
69             ->create({
70             organism_id => $organism->organism_id,
71             name        => $family_name,
72             uniquename  => $family_name,
73             type_id     => $family_name_type_id,
74         });
75     };
77     #add accession stock type for testing mixed types
78     push(@cross_ids, 'UG120001');
80     # create trial with cross stock type
81     ok(my $cross_trial_design = CXGN::Trial::TrialDesign->new(), "create trial design object");
82     ok($cross_trial_design->set_trial_name("cross_to_trial1"), "set trial name");
83     ok($cross_trial_design->set_stock_list(\@cross_ids), "set stock list");
84     ok($cross_trial_design->set_plot_start_number(1), "set plot start number");
85     ok($cross_trial_design->set_plot_number_increment(1), "set plot increment");
86     ok($cross_trial_design->set_number_of_blocks(2), "set block number");
87     ok($cross_trial_design->set_design_type("RCBD"), "set design type");
88     ok($cross_trial_design->calculate_design(), "calculate design");
89     ok(my $cross_design = $cross_trial_design->get_design(), "retrieve design");
91     my $preliminary_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'Preliminary Yield Trial', 'project_type')->cvterm_id();
93     ok(my $crosses_trial_create = CXGN::Trial::TrialCreate->new({
94         chado_schema      => $schema,
95         dbh               => $dbh,
96         owner_id          => 41,
97         design            => $cross_design,
98         program           => "test",
99         trial_year        => "2020",
100         trial_description => "test description",
101         trial_location    => "test_location",
102         trial_name        => "cross_to_trial1",
103         trial_type        => $preliminary_trial_cvterm_id,
104         design_type       => "RCBD",
105         operator          => "janedoe",
106         trial_stock_type  => "cross"
107     }), "create trial object");
109     my $crosses_trial_save = $crosses_trial_create->save_trial();
110     ok($crosses_trial_save->{'trial_id'}, "save trial");
113     # retrieving cross trial and design info
114     ok(my $crosses_trial_lookup = CXGN::Trial::TrialLookup->new({
115         schema     => $schema,
116         trial_name => "cross_to_trial1",
117     }), "create trial lookup object");
118     ok(my $crosses_trial = $crosses_trial_lookup->get_trial());
119     ok(my $cross_trial_id = $crosses_trial->project_id());
121     print STDERR "########## CREATING NEW TRIAL LAYOUT OBJECT \n";
122     my $cross_trial_layout;
123     ok($cross_trial_layout = CXGN::Trial::TrialLayout->new({
124         schema          => $schema,
125         trial_id        => $cross_trial_id,
126         experiment_type => 'field_layout'
127     }), "create trial layout object for cross trial");
129     my $cross_trial_design = $cross_trial_layout->get_design();
130     my @cross_plot_nums;
131     my @crosses;
132     my @cross_block_nums;
133     my @cross_plot_names;
135     print STDERR "CROSS LAYOUT = " . Dumper($cross_trial_design);
137     # note:cross and family_name stock types use the same accession_name key as accession stock type in trial design
138     foreach my $cross_plot_num (keys %$cross_trial_design) {
139         push @cross_plot_nums, $cross_plot_num;
140         push @crosses, $cross_trial_design->{$cross_plot_num}->{'accession_name'};
141         push @cross_block_nums, $cross_trial_design->{$cross_plot_num}->{'block_number'};
142         push @cross_plot_names, $cross_trial_design->{$cross_plot_num}->{'plot_name'};
144     }
145     @cross_plot_nums = sort @cross_plot_nums;
146     @crosses = sort @crosses;
147     @cross_block_nums = sort @cross_block_nums;
149     #is_deeply(\@cross_plot_nums, [
150     #        '1001',
151     #        '1002',
152     #        '1003',
153     #        '1004',
154     #        '1005',
155     #        '2001',
156     #        '2002',
157     #        '2003',
158     #        '2004',
159     #        '2005'
160     #    ], "check cross plot numbers");
162     is_deeply(\@crosses, [
163         'UG120001',
164         'UG120001',
165         'cross_for_trial1',
166         'cross_for_trial1',
167         'cross_for_trial2',
168         'cross_for_trial2',
169         'cross_for_trial3',
170         'cross_for_trial3',
171         'cross_for_trial4',
172         'cross_for_trial4',
173         'cross_for_trial5',
174         'cross_for_trial5'
175     ], "check cross unique ids");
177     is_deeply(\@cross_block_nums, [
178         '1',
179         '1',
180         '1',
181         '1',
182         '1',
183         '1',
184         '2',
185         '2',
186         '2',
187         '2',
188         '2',
189         '2'
190     ], "check cross block numbers");
192     is(scalar @cross_plot_names, 12);
194     my $cross_trial_type = CXGN::Trial->new({ bcs_schema => $schema, trial_id => $cross_trial_id });
195     my $cross_trial_stock_type = $cross_trial_type->get_trial_stock_type();
196     is($cross_trial_stock_type, 'cross');
198     #add accession for testing mixed stock types
199     push(@family_names, 'UG120001');
200     # create trial with family_name stock type
201     my $fam_trial_design;
202     ok($fam_trial_design = CXGN::Trial::TrialDesign->new(), "create trial design object");
203     ok($fam_trial_design->set_trial_name("family_name_to_trial1"), "set trial name");
204     ok($fam_trial_design->set_stock_list(\@family_names), "set stock list");
205     ok($fam_trial_design->set_plot_start_number(1), "set plot start number");
206     ok($fam_trial_design->set_plot_number_increment(1), "set plot increment");
207     ok($fam_trial_design->set_number_of_reps(2), "set rep number");
208     ok($fam_trial_design->set_design_type("CRD"), "set design type");
209     ok($fam_trial_design->calculate_design(), "calculate design");
211     my $fam_design;
212     ok($fam_design = $fam_trial_design->get_design(), "retrieve design");
214     my $fam_trial_create;
215     ok($fam_trial_create = CXGN::Trial::TrialCreate->new({
216         chado_schema      => $schema,
217         dbh               => $dbh,
218         owner_id          => 41,
219         design            => $fam_design,
220         program           => "test",
221         trial_year        => "2020",
222         trial_description => "test description",
223         trial_location    => "test_location",
224         trial_name        => "family_name_to_trial1",
225         trial_type        => $preliminary_trial_cvterm_id,
226         design_type       => "CRD",
227         operator          => "janedoe",
228         trial_stock_type  => "family_name"
229     }), "create trial object");
231     my $fam_save = $fam_trial_create->save_trial();
232     ok($fam_save->{'trial_id'}, "save trial");
235     # retrieving family_name trial with design info
236     ok(my $fam_trial_lookup = CXGN::Trial::TrialLookup->new({
237         schema     => $schema,
238         trial_name => "family_name_to_trial1",
239     }), "create trial lookup object");
240     ok(my $fam_trial = $fam_trial_lookup->get_trial());
241     ok(my $fam_trial_id = $fam_trial->project_id());
242     ok(my $fam_trial_layout = CXGN::Trial::TrialLayout->new({
243         schema          => $schema,
244         trial_id        => $fam_trial_id,
245         experiment_type => 'field_layout'
246     }), "create trial layout object for family trial");
248     my $fam_trial_design = $fam_trial_layout->get_design();
249     my @fam_plot_nums;
250     my @family_names;
251     my @fam_rep_nums;
252     my @fam_plot_names;
254     print STDERR "FAMILY TRIAL DESIGN: " . Dumper($fam_trial_design);
255     # note:cross and family_name stock types use the same accession_name key as accession stock type in trial design
256     foreach my $fam_plot_num (keys %$fam_trial_design) {
257         push @fam_plot_nums, $fam_plot_num;
258         push @family_names, $fam_trial_design->{$fam_plot_num}->{'accession_name'};
259         push @fam_rep_nums, $fam_trial_design->{$fam_plot_num}->{'rep_number'};
260         push @fam_plot_names, $fam_trial_design->{$fam_plot_num}->{'plot_name'};
261     }
262     @fam_plot_nums = sort @fam_plot_nums;
263     @family_names = sort @family_names;
264     @fam_rep_nums = sort @fam_rep_nums;
266     #is_deeply(\@fam_plot_nums, [
267     #        '1001',
268     #        '1002',
269     #        '1003',
270     #        '1004',
271     #        '1005',
272     #        '1006',
273     #        '1007',
274     #        '1008',
275     #        '1009',
276     #        '1010'
277     #    ], "check family_name plot numbers");
279     is_deeply(\@family_names, [
280         'UG120001',
281         'UG120001',
282         'family_name_for_trial1',
283         'family_name_for_trial1',
284         'family_name_for_trial2',
285         'family_name_for_trial2',
286         'family_name_for_trial3',
287         'family_name_for_trial3',
288         'family_name_for_trial4',
289         'family_name_for_trial4',
290         'family_name_for_trial5',
291         'family_name_for_trial5'
292     ], "check family names");
294     is_deeply(\@fam_rep_nums, [
295         '1',
296         '1',
297         '1',
298         '1',
299         '1',
300         '1',
301         '2',
302         '2',
303         '2',
304         '2',
305         '2',
306         '2'
307     ], "check fam rep numbers");
309     is(scalar @fam_plot_names, 12);
311     my $fam_trial_type = CXGN::Trial->new({ bcs_schema => $schema, trial_id => $fam_trial_id });
312     my $fam_trial_stock_type = $fam_trial_type->get_trial_stock_type();
313     is($fam_trial_stock_type, 'family_name');
316     # create cross trial Fieldbook
317     my $cross_fieldbook_tempfile = "/tmp/test_create_cross_trial_fieldbook.$extension";
319     my $cross_fieldbook = CXGN::Fieldbook::DownloadTrial->new({
320         bcs_schema       => $schema,
321         metadata_schema  => $metadata_schema,
322         phenome_schema   => $phenome_schema,
323         trial_id         => $cross_trial_id,
324         tempfile         => $cross_fieldbook_tempfile,
325         archive_path     => $fix->config->{archive_path},
326         user_id          => 41,
327         user_name        => "janedoe",
328         data_level       => 'plots',
329         selected_columns => { 'plot_name' => 1, 'plot_id' => 1, 'plot_number' => 1, 'block_number' => 1,, 'accession_name' => 1 },
330         trial_stock_type => 'cross'
331     });
333     my $create_fieldbook_return = $cross_fieldbook->download();
334     ok($create_fieldbook_return, "check that download trial fieldbook returns something.");
336     my $contents = ReadData $create_fieldbook_return->{'file'};
337     #print STDERR Dumper @contents->[0]->[0];
338     is($contents->[0]->{'type'}, $extension, "check that type of file is correct");
340     my $columns = $contents->[1]->{'cell'};
341     ok(scalar(@$columns) == 6, "check number of col in created file.");
342     my @field_book_columns = @$columns;
343     is($field_book_columns[1][1], 'plot_name');
344     is($field_book_columns[2][1], 'plot_id');
345     is($field_book_columns[3][1], 'cross_unique_id');
346     is($field_book_columns[4][1], 'plot_number');
347     is($field_book_columns[5][1], 'block_number');
348     print STDERR "FIELDBOOK COLUMNS =" . Dumper($columns) . "\n";
351     # create family_name trial Fieldbook
352     my $family_fieldbook_tempfile = "/tmp/test_create_family_trial_fieldbook.$extension";
354     my $family_fieldbook = CXGN::Fieldbook::DownloadTrial->new({
355         bcs_schema       => $schema,
356         metadata_schema  => $metadata_schema,
357         phenome_schema   => $phenome_schema,
358         trial_id         => $fam_trial_id,
359         tempfile         => $family_fieldbook_tempfile,
360         archive_path     => $fix->config->{archive_path},
361         user_id          => 41,
362         user_name        => "janedoe",
363         data_level       => 'plots',
364         selected_columns => { 'plot_name' => 1, 'plot_id' => 1, 'plot_number' => 1, 'rep_number' => 1,, 'accession_name' => 1 },
365         trial_stock_type => 'family_name'
366     });
368     my $create_family_fieldbook_return = $family_fieldbook->download();
369     ok($create_family_fieldbook_return, "check that download trial fieldbook returns something.");
371     my $family_contents = ReadData $create_family_fieldbook_return->{'file'};
372     #print STDERR Dumper @contents->[0]->[0];
373     is($family_contents->[0]->{'type'}, $extension, "check that type of file is correct");
375     my $family_columns = $family_contents->[1]->{'cell'};
376     ok(scalar(@$family_columns) == 6, "check number of col in created file.");
377     my @family_field_book_columns = @$family_columns;
378     is($family_field_book_columns[1][1], 'plot_name');
379     is($family_field_book_columns[2][1], 'plot_id');
380     is($family_field_book_columns[3][1], 'family_name');
381     is($family_field_book_columns[4][1], 'plot_number');
382     is($family_field_book_columns[5][1], 'rep_number');
383     print STDERR "FAMILY FIELDBOOK COLUMNS =" . Dumper($family_columns) . "\n";
386     #create westcott trial design_type using cross_unique_ids
388     my @cross_unique_ids_westcott;
389     for (my $i = 1; $i <= 100; $i++) {
390         push(@cross_unique_ids_westcott, "cross_for_westcott_trial" . $i);
391     }
393     foreach my $cross_unique_id (@cross_unique_ids_westcott) {
394         my $cross_stock = $schema->resultset('Stock::Stock')->create({
395             organism_id => $organism->organism_id,
396             name        => $cross_unique_id,
397             uniquename  => $cross_unique_id,
398             type_id     => $cross_type_id,
399         });
400     };
402     my $accession_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "accession", "stock_type")->cvterm_id();
404     my @accessions_westcott;
405     for (my $i = 1; $i <= 2; $i++) {
406         push @accessions_westcott, "check_accession_for_westcott_trial" . $i;
407     }
409     print STDERR "ACCESSIONS WESTCOTT: " . Dumper(\@accessions_westcott);
411     foreach my $accession (@accessions_westcott) {
412         my $accession_stock = $schema->resultset('Stock::Stock')->create(
413             {
414                 organism_id => $organism->organism_id,
415                 name        => $accession,
416                 uniquename  => $accession,
417                 #type_id     => $accession_type_id,
418                 type_id     => $cross_type_id,
419             });
420         print STDERR "Created accession $accession with type_id $accession_type_id\n";
421     }
423     ok(my $trial_design = CXGN::Trial::TrialDesign->new(), "create trial design object");
425     ok($trial_design->set_trial_name("cross_westcott_trial"), "set trial name");
426     ok($trial_design->set_stock_list(\@cross_unique_ids_westcott), "set stock list");
427     ok($trial_design->set_plot_start_number(1), "set plot start number");
428     ok($trial_design->set_plot_number_increment(1), "set plot increment");
429     ok($trial_design->set_westcott_check_1("check_accession_for_westcott_trial1"), "set check 1");
430     ok($trial_design->set_westcott_check_2("check_accession_for_westcott_trial2"), "set check 2");
431     ok($trial_design->set_westcott_col(20), "set column number");
432     ok($trial_design->set_design_type("Westcott"), "set design type");
433     ok($trial_design->calculate_design(), "calculate design");
434     ok(my $design = $trial_design->get_design(), "retrieve design");
436     ok(my $trial_create = CXGN::Trial::TrialCreate->new({
437         chado_schema      => $schema,
438         dbh               => $dbh,
439         owner_id          => 41,
440         design            => $design,
441         program           => "test",
442         trial_year        => "2015",
443         trial_description => "test description",
444         trial_location    => "test_location",
445         trial_name        => "cross_westcott_trial",
446         trial_type        => $preliminary_trial_cvterm_id,
447         design_type       => "Westcott",
448         operator          => "janedoe",
449         trial_stock_type  => 'cross'
450     }), "create trial object");
452     my $save = $trial_create->save_trial();
453     ok($save->{'trial_id'}, "save trial");
455     ok(my $trial_lookup = CXGN::Trial::TrialLookup->new({
456         schema     => $schema,
457         trial_name => "cross_westcott_trial",
458     }), "create trial lookup object");
460     ok(my $trial = $trial_lookup->get_trial());
461     ok(my $trial_id = $trial->project_id());
462     ok(my $trial_layout = CXGN::Trial::TrialLayout->new({
463         schema          => $schema,
464         trial_id        => $trial_id,
465         experiment_type => 'field_layout'
466     }), "create trial layout object for westcott trial");
468     ok(my $stock_names = $trial_layout->get_accession_names(), "retrieve cross_unique_ids");
470     print STDERR "STOCK NAMES IN WESTCOTT = " . Dumper($stock_names);
472     my %stocks = map {$_ => 1} @cross_unique_ids_westcott;
473     my @crosses;
474     for (my $i = 0; $i < scalar(@cross_unique_ids_westcott); $i++) {
475         foreach my $cross (@$stock_names) {
476             if ($cross->{accession_name} eq $cross_unique_ids_westcott[$i]) {
477                 push @crosses, $cross->{accession_name};
478             }
479         }
480     }
481     ok(scalar(@crosses) == 100, "check cross unique id");
483     my $mech = Test::WWW::Mechanize->new;
484     $mech->post_ok('http://localhost:3010/brapi/v1/token', [ "username" => "janedoe", "password" => "secretpw", "grant_type" => "password" ]);
485     my $response = decode_json $mech->content;
486     is($response->{'metadata'}->{'status'}->[2]->{'message'}, 'Login Successfull');
487     my $sgn_session_id = $response->{access_token};
488     print STDERR $sgn_session_id . "\n";
490     #test deleting a cross using in trial
491     my $cross_in_trial_id = $schema->resultset("Stock::Stock")->find({ name => 'cross_for_trial1' })->stock_id;
492     $mech->post_ok('http://localhost:3010/ajax/cross/delete', [ 'cross_id' => $cross_in_trial_id ]);
493     $response = decode_json $mech->content;
494     is_deeply($response, { 'error' => 'An error occurred attempting to delete a cross. (Cross has associated trial: cross_to_trial1. Cannot delete.
495 )' });
496     $fix->clean_up_db();
498 done_testing();