Эх сурвалжийг харах

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

George S. Baugh 9 жил өмнө
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::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.
+    - 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
     - 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
     autoclose=0
     encoding=UTF-8
+    configuration_group=Operating Systems
 
 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.
 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
     * test cases
     * 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.
 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_AUTOCLOSE'} = $params->{autoclose};
     $ENV{'TESTRAIL_ENCODING'}  = $params->{encoding};
+    $ENV{'TESTRIAL_CGROUP'}    = $params->{'configuration_group'};
     return $class;
 }
 

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

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

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

@@ -150,6 +150,7 @@ sub new {
         'encoding'     => delete $opts->{'encoding'},
         'sections'     => delete $opts->{'sections'},
         'autoclose'    => delete $opts->{'autoclose'},
+        'config_group' => delete $opts->{'config_group'},
         #Stubs for extension by subclassers
         'result_options'        => delete $opts->{'result_options'},
         'result_custom_options' => delete $opts->{'result_custom_options'}
@@ -209,6 +210,22 @@ sub new {
     #Grab run
     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
     @$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';

+ 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
     * test cases
     * 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.
 
@@ -2262,6 +2263,25 @@ sub getConfigurationGroups {
     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)>
 
 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 Test::LWP::UserAgent::TestRailMock;
 use Test::Rail::Parser;
-use Test::More 'tests' => 117;
+use Test::More 'tests' => 118;
 use Test::Fatal qw{exception};
 use Test::Deep qw{cmp_deeply};
 use Capture::Tiny qw{capture};
@@ -562,3 +562,16 @@ if (!$res) {
     $tap->run();
     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 Test::LWP::UserAgent::TestRailMock;
 
-use Test::More tests => 87;
+use Test::More tests => 88;
 use Test::Fatal;
 use Test::Deep;
 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");
 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");
 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',
                  'server' => 'Apache/2.4.7 (Ubuntu)'
                }, '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));
 
 }
@@ -1938,6 +1938,18 @@ $VAR5 = '[
         "id": 2,
         "name": "Operating Systems",
         "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));
@@ -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';