Browse Source

Fix #89 - Automatically add configurations/groups if specified by user

George S. Baugh 9 years ago
parent
commit
3e50abf6e5

+ 2 - 0
Changes

@@ -5,6 +5,8 @@ Revision history for Perl module TestRail::API
     - Add testrail-results binary and TestRail::Utils::Find::getResults.
     - Add testrail-results binary and TestRail::Utils::Find::getResults.
     - Add TestRail::API::getChildSections, and modify Test::Rail::Parser to recursively search passed sections when spawning runs
     - Add TestRail::API::getChildSections, and modify Test::Rail::Parser to recursively search passed sections when spawning runs
     - Change TestRail::API::getSections to cache the sections in a project.
     - Change TestRail::API::getSections to cache the sections in a project.
+    - Add notices about problems with duplicate entries to POD.
+    - Add capability to auto-spawn configurations/groups to App::Prove::Plugin::TestRail and friends when configuration_group is passed
 
 
 0.036 2016-04-25 TEODESIAN
 0.036 2016-04-25 TEODESIAN
     - Fix using wrong perl during testsuite when running binaries
     - Fix using wrong perl during testsuite when running binaries

+ 6 - 0
lib/App/Prove/Plugin/TestRail.pm

@@ -40,8 +40,12 @@ If \$HOME/.testrailrc exists, it will be parsed for any of these values in a new
     sections=section1:section2:section3: ... :sectionN
     sections=section1:section2:section3: ... :sectionN
     autoclose=0
     autoclose=0
     encoding=UTF-8
     encoding=UTF-8
+    configuration_group=Operating Systems
 
 
 Note that passing configurations as filters for runs inside of plans are separated by colons.
 Note that passing configurations as filters for runs inside of plans are separated by colons.
+
+If a configuration_group option is passed, it, and any configurations passed will be created automatically for you in the case they do not exist.
+
 Values passed in via query string will override values in \$HOME/.testrailrc.
 Values passed in via query string will override values in \$HOME/.testrailrc.
 If your system has no concept of user homes, it will look in the current directory for .testrailrc.
 If your system has no concept of user homes, it will look in the current directory for .testrailrc.
 
 
@@ -59,6 +63,7 @@ Also, all parameters expecting names are vulnerable to duplicate naming issues.
     * sections within the same testsuite that are peers
     * sections within the same testsuite that are peers
     * test cases
     * test cases
     * test plans and runs outside of plans which are not completed
     * test plans and runs outside of plans which are not completed
+    * configurations & configuration groups
 
 
 To do so will result in the first of said item found.
 To do so will result in the first of said item found.
 This might result in the reuse of an existing run/plan unintentionally, or spawning runs within the wrong project/testsuite or with incorrect test sections.
 This might result in the reuse of an existing run/plan unintentionally, or spawning runs within the wrong project/testsuite or with incorrect test sections.
@@ -117,6 +122,7 @@ sub load {
     $ENV{'TESTRAIL_SECTIONS'}  = $params->{sections};
     $ENV{'TESTRAIL_SECTIONS'}  = $params->{sections};
     $ENV{'TESTRAIL_AUTOCLOSE'} = $params->{autoclose};
     $ENV{'TESTRAIL_AUTOCLOSE'} = $params->{autoclose};
     $ENV{'TESTRAIL_ENCODING'}  = $params->{encoding};
     $ENV{'TESTRAIL_ENCODING'}  = $params->{encoding};
+    $ENV{'TESTRIAL_CGROUP'}    = $params->{'configuration_group'};
     return $class;
     return $class;
 }
 }
 
 

+ 1 - 0
lib/Test/Rail/Harness.pm

@@ -56,6 +56,7 @@ sub make_parser {
     $args->{'step_results'}   = $ENV{'TESTRAIL_STEPS'};
     $args->{'step_results'}   = $ENV{'TESTRAIL_STEPS'};
     $args->{'testsuite_id'}   = $ENV{'TESTRAIL_SPAWN'};
     $args->{'testsuite_id'}   = $ENV{'TESTRAIL_SPAWN'};
     $args->{'testsuite'}      = $ENV{'TESTRAIL_TESTSUITE'};
     $args->{'testsuite'}      = $ENV{'TESTRAIL_TESTSUITE'};
+    $args->{'config_group'}   = $ENV{'TESTRAIL_CGROUP'};
 
 
     @sections = split(/:/,$ENV{'TESTRAIL_SECTIONS'}) if $ENV{'TESTRAIL_SECTIONS'};
     @sections = split(/:/,$ENV{'TESTRAIL_SECTIONS'}) if $ENV{'TESTRAIL_SECTIONS'};
     $args->{'sections'}  = \@sections if scalar(@sections);
     $args->{'sections'}  = \@sections if scalar(@sections);

+ 17 - 0
lib/Test/Rail/Parser.pm

@@ -150,6 +150,7 @@ sub new {
         'encoding'     => delete $opts->{'encoding'},
         'encoding'     => delete $opts->{'encoding'},
         'sections'     => delete $opts->{'sections'},
         'sections'     => delete $opts->{'sections'},
         'autoclose'    => delete $opts->{'autoclose'},
         'autoclose'    => delete $opts->{'autoclose'},
+        'config_group' => delete $opts->{'config_group'},
         #Stubs for extension by subclassers
         #Stubs for extension by subclassers
         'result_options'        => delete $opts->{'result_options'},
         'result_options'        => delete $opts->{'result_options'},
         'result_custom_options' => delete $opts->{'result_custom_options'}
         'result_custom_options' => delete $opts->{'result_custom_options'}
@@ -209,6 +210,22 @@ sub new {
     #Grab run
     #Grab run
     my ($run,$plan,$config_ids);
     my ($run,$plan,$config_ids);
 
 
+    # See if we have to create a configuration
+    my $configz2create = $tr->getConfigurations($tropts->{'project_id'});
+    @$configz2create = grep { my $c = $_; (grep { $_ eq $c->{'name'} } @{$tropts->{'configs'}}) } @$configz2create;
+    if (scalar(@$configz2create) && $tropts->{'config_group'}) {
+        my $cgroup = $tr->getConfigurationGroupByName($tropts->{project_id},$tropts->{'config_group'});
+        unless (ref($cgroup) eq 'HASH') {
+            print "# Adding Configuration Group $tropts->{config_group}...\n";
+            $cgroup = $tr->addConfigurationGroup($tropts->{project_id},$tropts->{'config_group'});
+        }
+        confess("Could neither find nor create the provided configuration group '$tropts->{config_group}'") unless ref($cgroup) eq 'HASH';
+        foreach my $cc (@$configz2create) {
+            print "# Adding Configuration $cc->{name}...\n";
+            $tr->addConfiguration($cgroup->{'id'}, $cc->{'name'});
+        }
+    }
+
     #check if configs passed are defined for project.  If we can't get all the IDs, something's hinky
     #check if configs passed are defined for project.  If we can't get all the IDs, something's hinky
     @$config_ids = $tr->translateConfigNamesToIds($tropts->{'project_id'},@{$tropts->{'configs'}});
     @$config_ids = $tr->translateConfigNamesToIds($tropts->{'project_id'},@{$tropts->{'configs'}});
     confess("Could not retrieve list of valid configurations for your project.") unless (reftype($config_ids) || 'undef') eq 'ARRAY';
     confess("Could not retrieve list of valid configurations for your project.") unless (reftype($config_ids) || 'undef') eq 'ARRAY';

+ 20 - 0
lib/TestRail/API.pm

@@ -28,6 +28,7 @@ Also, all *ByName methods are vulnerable to duplicate naming issues.  Try not to
     * sections within the same testsuite that are peers
     * sections within the same testsuite that are peers
     * test cases
     * test cases
     * test plans and runs outside of plans which are not completed
     * test plans and runs outside of plans which are not completed
+    * configurations
 
 
 To do so will result in the first of said item found being returned rather than an array of possibilities to choose from.
 To do so will result in the first of said item found being returned rather than an array of possibilities to choose from.
 
 
@@ -2262,6 +2263,25 @@ sub getConfigurationGroups {
     return $self->_doRequest($url);
     return $self->_doRequest($url);
 }
 }
 
 
+=head2 B<getConfigurationGroupByName(project_id,name)>
+
+Get the provided configuration group by name.
+
+Returns false if the configuration group could not be found.
+
+=cut
+
+sub getConfigurationGroupByName {
+    state $check = compile(Object, Int, Str);
+    my ($self,$project_id,$name) = $check->(@_);
+
+    my $cgroups = $self->getConfigurationGroups($project_id);
+    return 0 if ref($cgroups) ne 'ARRAY';
+    @$cgroups = grep {$_->{'name'} eq $name} @$cgroups;
+    return 0 unless scalar(@$cgroups);
+    return $cgroups->[0];
+}
+
 =head2 B<addConfigurationGroup(project_id,name)>
 =head2 B<addConfigurationGroup(project_id,name)>
 
 
 New in TestRail 5.2.
 New in TestRail 5.2.

+ 14 - 1
t/Test-Rail-Parser.t

@@ -10,7 +10,7 @@ use Scalar::Util qw{reftype};
 use TestRail::API;
 use TestRail::API;
 use Test::LWP::UserAgent::TestRailMock;
 use Test::LWP::UserAgent::TestRailMock;
 use Test::Rail::Parser;
 use Test::Rail::Parser;
-use Test::More 'tests' => 117;
+use Test::More 'tests' => 118;
 use Test::Fatal qw{exception};
 use Test::Fatal qw{exception};
 use Test::Deep qw{cmp_deeply};
 use Test::Deep qw{cmp_deeply};
 use Capture::Tiny qw{capture};
 use Capture::Tiny qw{capture};
@@ -562,3 +562,16 @@ if (!$res) {
     $tap->run();
     $tap->run();
     is($tap->{'errors'},0,"No errors encountered uploading case results");
     is($tap->{'errors'},0,"No errors encountered uploading case results");
 }
 }
+
+#Check configuration group spawn is done correctly
+undef $opts->{'tap'};
+$opts->{'source'} = 't/pass.test';
+$opts->{'project_id'} = 9;
+$opts->{'run'} = 'TestingSuite';
+$opts->{'plan'} = 'mah dubz plan';
+$opts->{'config_group'} = 'noSuchGroup';
+$opts->{'configs'}      = ['noSuchConfig'];
+$opts->{'sections'} = [];
+
+$res = exception { $tap = Test::Rail::Parser->new($opts) };
+is($res,undef,"TR Parser runs all the way through when spawning configurations");

+ 4 - 1
t/TestRail-API.t

@@ -7,7 +7,7 @@ use lib "$FindBin::Bin/lib";
 use TestRail::API;
 use TestRail::API;
 use Test::LWP::UserAgent::TestRailMock;
 use Test::LWP::UserAgent::TestRailMock;
 
 
-use Test::More tests => 87;
+use Test::More tests => 88;
 use Test::Fatal;
 use Test::Fatal;
 use Test::Deep;
 use Test::Deep;
 use Scalar::Util ();
 use Scalar::Util ();
@@ -231,6 +231,9 @@ is_deeply(\@config_ids,\@t_config_ids, "Can correctly translate Project names to
 my $grp = $tr->addConfigurationGroup($new_project->{'id'},"zippy");
 my $grp = $tr->addConfigurationGroup($new_project->{'id'},"zippy");
 is($grp->{'name'},'zippy',"Can add configuration group successfully");
 is($grp->{'name'},'zippy',"Can add configuration group successfully");
 
 
+my $fetchedgrp = $tr->getConfigurationGroupByName($new_project->{'id'},'zippy');
+is($fetchedgrp->{'id'},$grp->{'id'},"Can get configuration group by name");
+
 my $newgrp = $tr->editConfigurationGroup($grp->{'id'},"doodah");
 my $newgrp = $tr->editConfigurationGroup($grp->{'id'},"doodah");
 is($newgrp->{'name'},'doodah',"Can edit configuration group successfully");
 is($newgrp->{'name'},'doodah',"Can edit configuration group successfully");
 
 

+ 41 - 1
t/lib/Test/LWP/UserAgent/TestRailMock.pm

@@ -1431,7 +1431,7 @@ $VAR4 = bless( {
                  'content-type' => 'application/json; charset=utf-8',
                  'content-type' => 'application/json; charset=utf-8',
                  'server' => 'Apache/2.4.7 (Ubuntu)'
                  'server' => 'Apache/2.4.7 (Ubuntu)'
                }, 'HTTP::Headers' );
                }, 'HTTP::Headers' );
-$VAR5 = '[{"display_order":1,"system_name":"custom_step_results","name":"step_results","description":"Step by step results","is_active":1,"type_id":11,"configs":[{"options":{"is_required":0,"format":"markdown","has_actual":1,"has_expected":1},"context":{"project_ids":[5,3],"is_global":1},"id":"43410543-edaf-44d2-91fc-58a6f9b3f743"},{"options":{"is_required":1,"format":"markdown","has_actual":1,"has_expected":1},"context":{"project_ids":[1],"is_global":1},"id":"0ab86184-0468-40d8-a385-a9b3a1ec41a4"},{"options":{"is_required":0,"format":"markdown","has_actual":1,"has_expected":1},"context":{"project_ids":[10],"is_global":1},"id":"43ebdf1f-c9b9-4b91-a729-5c9f21252f00"}],"id":6,"label":"Step Results"}]';
+$VAR5 = '[{"display_order":1,"system_name":"custom_step_results","name":"step_results","description":"Step by step results","is_active":1,"type_id":11,"configs":[{"options":{"is_required":0,"format":"markdown","has_actual":1,"has_expected":1},"context":{"project_ids":[5,3,9],"is_global":1},"id":"43410543-edaf-44d2-91fc-58a6f9b3f743"},{"options":{"is_required":1,"format":"markdown","has_actual":1,"has_expected":1},"context":{"project_ids":[1],"is_global":1},"id":"0ab86184-0468-40d8-a385-a9b3a1ec41a4"},{"options":{"is_required":0,"format":"markdown","has_actual":1,"has_expected":1},"context":{"project_ids":[10],"is_global":1},"id":"43ebdf1f-c9b9-4b91-a729-5c9f21252f00"}],"id":6,"label":"Step Results"}]';
 $mockObject->map_response(qr/\Q$VAR1\E/,HTTP::Response->new($VAR2, $VAR3, $VAR4, $VAR5));
 $mockObject->map_response(qr/\Q$VAR1\E/,HTTP::Response->new($VAR2, $VAR3, $VAR4, $VAR5));
 
 
 }
 }
@@ -1938,6 +1938,18 @@ $VAR5 = '[
         "id": 2,
         "id": 2,
         "name": "Operating Systems",
         "name": "Operating Systems",
         "project_id": 1
         "project_id": 1
+    },
+    {
+        "configs": [
+        {
+            "group_id": 3,
+            "id": 666,
+            "name": "noSuchConfig"
+        }
+        ],
+        "id": 3,
+        "name": "zippy",
+        "project_id": 1
     }
     }
 ]';
 ]';
 $mockObject->map_response(qr/\Q$VAR1\E/,HTTP::Response->new($VAR2, $VAR3, $VAR4, $VAR5));
 $mockObject->map_response(qr/\Q$VAR1\E/,HTTP::Response->new($VAR2, $VAR3, $VAR4, $VAR5));
@@ -2966,6 +2978,34 @@ $mockObject->map_response(qr/\Q$VAR1\E/,HTTP::Response->new($VAR2, $VAR3, $VAR4,
 
 
 }
 }
 
 
+{
+
+$VAR1 = 'index.php?/api/v2/get_sections/9&suite_id=5';
+$VAR2 = '200';
+$VAR3 = 'OK';
+$VAR4 = bless( {
+                 '::std_case' => {
+                                   'client-response-num' => 'Client-Response-Num',
+                                   'client-peer' => 'Client-Peer',
+                                   'x-powered-by' => 'X-Powered-By',
+                                   'client-date' => 'Client-Date'
+                                 },
+                 'client-date' => 'Wed, 10 Aug 2016 03:07:52 GMT',
+                 'date' => 'Wed, 10 Aug 2016 03:07:51 GMT',
+                 'connection' => 'close',
+                 'x-powered-by' => 'PHP/5.5.9-1ubuntu4.14',
+                 'content-length' => '835',
+                 'content-type' => 'application/json; charset=utf-8',
+                 'client-peer' => '192.168.122.217:80',
+                 'client-response-num' => 1,
+                 'server' => 'Apache/2.4.7 (Ubuntu)'
+               }, 'HTTP::Headers' );
+$VAR5 = '[{"id":6,"suite_id":5,"name":"Column A","description":null,"parent_id":null,"display_order":1,"depth":0},{"id":8,"suite_id":5,"name":"zippy","description":null,"parent_id":6,"display_order":2,"depth":1},{"id":7,"suite_id":5,"name":"Column B","description":null,"parent_id":null,"display_order":3,"depth":0},{"id":9,"suite_id":5,"name":"zippy","description":null,"parent_id":7,"display_order":4,"depth":1},{"id":11,"suite_id":5,"name":"Recursing section","description":null,"parent_id":null,"display_order":5,"depth":0},{"id":12,"suite_id":5,"name":"child","description":null,"parent_id":11,"display_order":6,"depth":1},{"id":13,"suite_id":5,"name":"grandchild","description":null,"parent_id":12,"display_order":7,"depth":2},{"id":14,"suite_id":5,"name":"great-grandchild","description":null,"parent_id":13,"display_order":8,"depth":3}]';
+$mockObject->map_response(qr/\Q$VAR1\E/,HTTP::Response->new($VAR2, $VAR3, $VAR4, $VAR5));
+
+}
+
+
 {
 {
 
 
 $VAR1 = 'index.php?/api/v2/get_configs/3';
 $VAR1 = 'index.php?/api/v2/get_configs/3';