Prepare 2.4 release. Updated webservice to allow struct params.

git-svn-id: svn://10.0.0.236/trunk@260835 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mkanat%bugzilla.org 2010-07-21 17:31:16 +00:00
parent f6b9eac46c
commit b36591329f
43 changed files with 2597 additions and 2330 deletions

View File

@ -0,0 +1,2 @@
Testopiatestopia.all.js.log.txt
Testopiatestopia.all.js.log.txt

View File

@ -1 +1 @@
639
640

View File

@ -1,10 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>testopia-1.0-2.22</name>
<name>testopia</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.rockstarapps.html.refactoring.WebOptimizer</name>
<arguments>
<dictionary>
<key>extensions/Testopia/testopia.all.js</key>
<value>&lt;data&gt;&lt;fileName&gt;extensions/Testopia/testopia.all.js&lt;/fileName&gt;&lt;min&gt;false&lt;/min&gt;&lt;comp&gt;true&lt;/comp&gt;&lt;gZip&gt;false&lt;/gZip&gt;&lt;resolveImports&gt;false&lt;/resolveImports&gt;&lt;urlRewriting&gt;false&lt;/urlRewriting&gt;&lt;autoBuild&gt;true&lt;/autoBuild&gt;&lt;lineLength&gt;-1&lt;/lineLength&gt;&lt;dependencies&gt;&lt;file&gt;extensions/Testopia/js/strings.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/vars.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/util.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/attachments.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/plan.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/case.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/caserun.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/run.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/build.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/category.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/diff-tabs.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/environment.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/product.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/search.js&lt;/file&gt;&lt;file&gt;extensions/Testopia/js/tags.js&lt;/file&gt;&lt;/dependencies&gt;&lt;/data&gt;</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.epic.perleditor.perlbuilder</name>
<arguments>

View File

@ -6,10 +6,10 @@ organizations to integrate bug reporting with their test case run results.
Though it is designed with software testing in mind, it can be used to track
testing on virtually anything in the engineering process.
The following installation instructions assume you are installing the latest version of Testopia, currently version 2.3.
The following installation instructions assume you are installing the latest version of Testopia, currently version 2.4.
=== Requirements ===
* Bugzilla 3.4.3+
* Bugzilla 3.6+
* Perl JSON 2.10
* GD-Graph3d 0.63
@ -17,9 +17,15 @@ Testopia is an extension to Bugzilla. This means that if you have one of the
supported versions of Bugzilla installed, you are all set to install Testopia.
Installation instructions for Bugzilla can be found at http://bugzilla.org
'''IMPORTANT NOTE:''' These instructions assume you have installed Bugzilla according to the Bugzilla instructions (from tarball or cvs). Installations from Debian .deb or from some RPM packages may place Bugzilla files in separate directories in which case, these will not work.
'''IMPORTANT NOTE:'''
These instructions assume you have installed Bugzilla according to the Bugzilla
instructions (from tarball or cvs). Installations from Debian .deb or from some
RPM packages may place Bugzilla files in separate directories in which case,
these instructions may not work.
Please make sure that your language of Bugzilla is the same as language of Testopia to be installed on. If you are not sure, just set language of your Bugzilla to English. You can change it any time later.
Please make sure that your language of Bugzilla is the same as language of
Testopia to be installed on. If you are not sure, just set language of your
Bugzilla to English. You can change it any time later.
=== Installation on Linux ===
@ -32,16 +38,18 @@ something like this:
$> cd /path/to/bugzilla
$> tar xzvf testopia-<version>.tar.gz
Next you need to patch the Bugzilla files. Find the patch file in the extensions/Testopia directory matching your version of Bugzilla.
For example, if you are running Bugzilla 3.4.3 you will apply the patch-3.4.3 patch file.
Next you need to patch the Bugzilla files. Find the patch file in the
extensions/Testopia directory matching your version of Bugzilla.
For example, if you are running Bugzilla 3.6.1 you will apply the patch-3.6.1 patch file.
$> patch -p0 -i extensions/Testopia/patch-3.4.3
$> patch -p0 -i extensions/Testopia/patch-3.6.1
Finally, you need to run checksetup.pl
$> ./checksetup.pl
If you are missing any dependencies, checksetup.pl will inform you. See "Installing Dependencies".
If you are missing any dependencies, checksetup.pl will inform you.
See "Installing Dependencies".
''' From CVS: '''
@ -64,19 +72,23 @@ Bugzilla from CVS, be sure to delete the top level CVS directory first.
$> rm -rf CVS
$> tar cvf /tmp/testopia.tar .
Once you have your tarball, follow the tarball instructions above to untar it into your Bugzilla directory The last step is to install the Ext libraries:
Once you have your tarball, follow the tarball instructions above to untar
it into your Bugzilla directory The last step is to install the Ext libraries:
$> cd path/to/bugzilla/testopia/
$> wget http://extjs.com/deploy/ext-3.0.1.zip
$> unzip ext-3.0.1.zip
$> mv ext-3.0.1 extjs
$> wget http://extjs.com/deploy/ext-3.2.1.zip
$> unzip ext-3.2.1.zip
$> mv ext-3.2.1 extjs
Congratulations, you should be able to see the Testopia links at the bottom of
your bugzilla pages.
=== Installation on Windows ===
Windows installations are not officially supported. By this we mean don't ask the developers for help as we have never tried to install on Windows and don't have any desire to. However, there have been numerous users that have managed to do so on their own. Here are some pointers:
Windows installations are not officially supported. By this we mean don't ask
the developers for help as we have never tried to install on Windows and don't
have any desire to. However, there have been numerous users that have managed
to do so on their own. Here are some pointers:
*Add a .txt file extension to your corresponding patch file (\bugzilla\testopia\patch-3.0[.x]).
*Edit the above patch file to remove *nix line feed characters, and putting in classic DOS/Windows carriage returns.<br>You can do this manually, or with WordPad (write.exe) or numerous utilities such as unix2dos or tofrodos.

View File

@ -142,35 +142,37 @@ if (defined($Bugzilla_login)) {
}
}
$soapresult = $proxy->call('Testopia.testopia_version');
#$soapresult = $proxy->call('Bugzilla.version');
#$soapresult = $proxy->call('Bugzilla.extensions');
#$soapresult = $proxy->call('Testopia.testopia_version');
#$soapresult = $proxy->call('Testopia.api_version');
#####################
### Build Methods ###
#####################
#$soapresult = $proxy->call('Build.check_build', 'Linux', 2);
#$soapresult = $proxy->call('Build.check_build', 'Linux', 'Bugzilla');
#$soapresult = $proxy->call('Build.check_build', 'Linux', Bugzilla::Extension::Testopia::Product->new(2));
#$soapresult = $proxy->call('Build.create', {name=>'Build '. time(), product_id=>2, isactive=>0, description=> 'API Test Build - IGNORE'});
#$soapresult = $proxy->call('Build.get', 1140);
#$soapresult = $proxy->call('Build.update', 1140, { description=>'This is a description', milestone=>'3.0', isactive=>0});
#$soapresult = $proxy->call('Build.check_build', {name => 'Linux', product => 1});
#$soapresult = $proxy->call('Build.check_build', {name => 'Linux', product => 'TestProduct'});
#$soapresult = $proxy->call('Build.create', {name=>'Build '. time(), product_id=>1, isactive=>0, description=> 'API Test Build - IGNORE'});
#$soapresult = $proxy->call('Build.get', {id => 1});
#$soapresult = $proxy->call('Build.get_caseruns', {id => 1});
#$soapresult = $proxy->call('Build.get_runs', {id => 1});
#$soapresult = $proxy->call('Build.update', { id => 1, description=>'This is a description', milestone=>'---', isactive=>0});
###########################
### Environment Methods ###
###########################
#$soapresult = $proxy->call('Environment.check_environment', 'Linux', 2);
#$soapresult = $proxy->call('Environment.check_environment', 'Linux', 'Bugzilla');
#$soapresult = $proxy->call('Environment.check_environment', 'Linux', Bugzilla::Extension::Testopia::Product->new(2));
#$soapresult = $proxy->call('Environment.create', {product_id=>2, name=>'Environment '.time() , isactive=>1});
#$soapresult = $proxy->call('Environment.get', 1018);
#$soapresult = $proxy->call('Environment.list', {environment_id=>330});
#$soapresult = $proxy->call('Environment.check_environment', {name => 'Linux', product => 1});
#$soapresult = $proxy->call('Environment.check_environment', {name => 'Linux', product => 'TestProduct'});
#$soapresult = $proxy->call('Environment.create', {product_id=>1, name=>'Environment '.time() , isactive=>1});
#$soapresult = $proxy->call('Environment.get', {id => 1});
#$soapresult = $proxy->call('Environment.list', {environment_id=>1});
#$soapresult = $proxy->call('Environment.list', {name=>'Linux'});
#$soapresult = $proxy->call('Environment.update', 1018, {name=>'Second Environment'});
#$soapresult = $proxy->call('Environment.get_runs', 1);
#$soapresult = $proxy->call('Environment.get_caseruns', 1);
#$soapresult = $proxy->call('Environment.create_full', "My Environment", 2,
# {
#$soapresult = $proxy->call('Environment.update', {id=>1, name=>'Second Environment'});
#$soapresult = $proxy->call('Environment.get_runs', {id => 1});
#$soapresult = $proxy->call('Environment.get_caseruns', {id => 1});
#$soapresult = $proxy->call('Environment.create_full', {name => "My Environment", product => 1,
# environment => {
# Database => {
# Looly =>{
# lum => 'lee',
@ -180,129 +182,126 @@ $soapresult = $proxy->call('Testopia.testopia_version');
# lor => 'lee'
# }
# }
# });
# }});
#######################
### Product Methods ###
#######################
#$soapresult = $proxy->call('Product.get', 2);
#$soapresult = $proxy->call('Product.check_product', 'Bugzilla');
#$soapresult = $proxy->call('Product.check_category', 'CGI', 'Bugzilla');
#$soapresult = $proxy->call('Product.get_builds', 2);
#$soapresult = $proxy->call('Product.get_cases', 2);
#$soapresult = $proxy->call('Product.get_categories', 2);
#$soapresult = $proxy->call('Product.get_components', 2);
#$soapresult = $proxy->call('Product.get_component', 3929);
#$soapresult = $proxy->call('Product.get_environments', 2);
#$soapresult = $proxy->call('Product.get_milestones', 2);
#$soapresult = $proxy->call('Product.get_plans', 2);
#$soapresult = $proxy->call('Product.get_runs', 2);
#$soapresult = $proxy->call('Product.get_tags', 2);
#$soapresult = $proxy->call('Product.get_versions', 2);
#$soapresult = $proxy->call('TestopiaProduct.check_product', {name => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.check_category', {name => '--default--', product => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get', {id => 1});
#$soapresult = $proxy->call('TestopiaProduct.get', {name => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get_builds', {name => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get_cases', {id => 1});
#$soapresult = $proxy->call('TestopiaProduct.get_categories', {name => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get_components', {name => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get_component', {id=>1});
#$soapresult = $proxy->call('TestopiaProduct.get_component', {name => 'TestComponent', product => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get_environments', {name => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get_milestones', {name => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get_plans', {name => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get_runs', {name => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get_tags', {name => 'TestProduct'});
#$soapresult = $proxy->call('TestopiaProduct.get_versions', {name => 'TestProduct'});
########################
### TestCase Methods ###
########################
#$soapresult = $proxy->call('TestCase.add_component', [278,304],[2,3,4]);
#$soapresult = $proxy->call('TestCase.add_component', [278,304],[{product => "Bugzilla", component => "General"}]);
#$soapresult = $proxy->call('TestCase.add_tag', [278,304], ['Fred','Fish']);
#$soapresult = $proxy->call('TestCase.add_to_run', [278,306], [1700,1701]);
#$soapresult = $proxy->call('TestCase.attach_bug', [278,306], [33,44]);
#$soapresult = $proxy->call('TestCase.calculate_average_time', 278);
#$soapresult = $proxy->call('TestCase.create', {case_status_id => 'CONFIRMED', category_id => 'CGI', priority_id => 'P5 - None', summary => 'API TEST CASE', plans => [74]});
#$soapresult = $proxy->call('TestCase.create', [{case_status_id => 'CONFIRMED', category_id => 'CGI', priority_id => 'P5 - None', summary => 'API TEST CASE', plans => [74]}]);
#$soapresult = $proxy->call('TestCase.detach_bug', 278, 33);
#$soapresult = $proxy->call('TestCase.get', 278);
#$soapresult = $proxy->call('TestCase.get_bugs', 278);
#$soapresult = $proxy->call('TestCase.get_case_run_history', 278);
#$soapresult = $proxy->call('TestCase.get_change_history', 278);
#$soapresult = $proxy->call('TestCase.get_components', 278);
#$soapresult = $proxy->call('TestCase.get_plans', 278);
#$soapresult = $proxy->call('TestCase.get_tags', 278);
#$soapresult = $proxy->call('TestCase.get_text', 278,3);
#$soapresult = $proxy->call('TestCase.link_plan', 278, [77,78]);
#$soapresult = $proxy->call('TestCase.add_component', {case_ids => [1,2], components => [1]});
#$soapresult = $proxy->call('TestCase.add_component', {case_ids => [1,2], components => [{product => "TestProduct", component => "TestComponent"}]});
#$soapresult = $proxy->call('TestCase.add_tag', {case_ids => [1,2], tags => ['Fred','Fish']});
#$soapresult = $proxy->call('TestCase.add_to_run', {case_ids => [1,2], run_ids => [1,2]});
#$soapresult = $proxy->call('TestCase.attach_bug', {case_ids =>[1,2], bug_ids => [1,2]});
#$soapresult = $proxy->call('TestCase.calculate_average_time', {id => 1});
#$soapresult = $proxy->call('TestCase.create', {status => 'CONFIRMED', category => '--default--', priority => 'Low', summary => 'API TEST CASE', plans => [1]});
#$soapresult = $proxy->call('TestCase.create', [{status => 'CONFIRMED', category => '--default--', priority => 'Low', summary => 'API TEST CASE', plans => [1]}]);
#$soapresult = $proxy->call('TestCase.detach_bug', {case_id => 1, bug_ids => 1});
#$soapresult = $proxy->call('TestCase.get', {id => 1});
#$soapresult = $proxy->call('TestCase.get_bugs', {id => 1});
#$soapresult = $proxy->call('TestCase.get_case_run_history', {id => 1});
#$soapresult = $proxy->call('TestCase.get_change_history', {id => 1});
#$soapresult = $proxy->call('TestCase.get_components', {id => 1});
#$soapresult = $proxy->call('TestCase.get_plans', {id => 1});
#$soapresult = $proxy->call('TestCase.get_tags', {id => 1});
#$soapresult = $proxy->call('TestCase.get_text', {case_id => 1, version => 1});
#$soapresult = $proxy->call('TestCase.link_plan', {case_id => 1, plan_ids => [1,2]});
#$soapresult = $proxy->call('TestCase.list', {default_tester => 'ghendricks@novell.com'});
#$soapresult = $proxy->call('TestCase.list', {pagesize => 1000, page => 0, isautomated => 1});
#$soapresult = $proxy->call('TestCase.lookup_category_id_by_name' );
#$soapresult = $proxy->call('TestCase.lookup_category_name_by_id' );
#$soapresult = $proxy->call('TestCase.lookup_priority_id_by_name', 'P5 - None');
#$soapresult = $proxy->call('TestCase.lookup_priority_name_by_id', 3);
#$soapresult = $proxy->call('TestCase.lookup_status_id_by_name', 'CONFIRMED');
#$soapresult = $proxy->call('TestCase.lookup_status_name_by_id', 1);
#$soapresult = $proxy->call('TestCase.remove_component', 278,2);
#$soapresult = $proxy->call('TestCase.remove_tag', 278, 'fish');
#$soapresult = $proxy->call('TestCase.store_text', 278, 'vrb@novell.com', 'FOO', 'FISH', 'FIGHT', 'FUN');
#$soapresult = $proxy->call('TestCase.unlink_plan', 278, 78);
#$soapresult = $proxy->call('TestCase.update', 278,{priority_id => 'P2 - High', case_status_id=>3 ,summary=>'This was Entering bugs', category_id => '142'});
#$soapresult = $proxy->call('TestCase.update',435838 ,{ summary => 'API TEST', category_id => '1666'});
#$soapresult = $proxy->call('TestCase.update',[33,44,55] ,{ summary => 'API TEST'});
#$soapresult = $proxy->call('TestCase.lookup_priority_id_by_name', {name => 'Low'});
#$soapresult = $proxy->call('TestCase.lookup_priority_name_by_id', {id => 3});
#$soapresult = $proxy->call('TestCase.lookup_status_id_by_name', {name =>'CONFIRMED'});
#$soapresult = $proxy->call('TestCase.lookup_status_name_by_id', {id => 1});
#$soapresult = $proxy->call('TestCase.remove_component', {case_ids => [1], component_id => 1});
#$soapresult = $proxy->call('TestCase.remove_tag', {case_ids => [1], tag => 'fish'});
#$soapresult = $proxy->call('TestCase.store_text', {case_id => 1, action => 'FOO', effect => 'FISH', setup => 'FIGHT', breakdown => 'FUN', author_id => 'ghendricks@novell.com'});
#$soapresult = $proxy->call('TestCase.unlink_plan', {case_id => 1, plan_id => 1});
#$soapresult = $proxy->call('TestCase.update', {ids => [1], priority_id => 'High', case_status_id=>3 ,summary=>'This was Entering bugs', category_id => '1'});
###########################
### TestCaseRun Methods ###
###########################
#$soapresult = $proxy->call('TestCaseRun.attach_bug', 65104, [33,44] );
#$soapresult = $proxy->call('TestCaseRun.create', {case_id => 765, run_id => 501, build_id => 306, environment_id =>7});
#$soapresult = $proxy->call('TestCaseRun.detach_bug', 65104, 33);
#$soapresult = $proxy->call('TestCaseRun.get', 65104);
#$soapresult = $proxy->call('TestCaseRun.get', 501, 765, 306, 1);
#$soapresult = $proxy->call('TestCaseRun.get_bugs', 65104);
#$soapresult = $proxy->call('TestCaseRun.get_completion_time', 65104);
#$soapresult = $proxy->call('TestCaseRun.get_history',65104 );
#$soapresult = $proxy->call('TestCaseRun.list', {pagesize => 1000, page => 0, run_id => 6459, isautomated => 1, isactive=>0});
#$soapresult = $proxy->call('TestCaseRun.attach_bug', {case_id => 1, run_id => 6, build_id => 1, env_id => 2, bug_ids => [1,2]} );
#$soapresult = $proxy->call('TestCaseRun.attach_bug', {id => 1, bug_ids => 1});
#$soapresult = $proxy->call('TestCaseRun.create', {case_id => 1, run_id => 1, build_id => 1, environment_id => 1});
#$soapresult = $proxy->call('TestCaseRun.detach_bug', {id => 5, bug_id => 3});
#$soapresult = $proxy->call('TestCaseRun.get', {id => 1});
#$soapresult = $proxy->call('TestCaseRun.get', {case_id => 1, run_id => 1, build_id => 1, env_id => 1});
#$soapresult = $proxy->call('TestCaseRun.get_bugs', {id => 3});
#$soapresult = $proxy->call('TestCaseRun.get_bugs', {case_id => 3, run_id => 1, build_id => 1, env_id=>1});
#$soapresult = $proxy->call('TestCaseRun.get_completion_time', {id => 3});
#$soapresult = $proxy->call('TestCaseRun.get_history', {id => 3});
#$soapresult = $proxy->call('TestCaseRun.list', {pagesize => 1000, page => 0, run_id => 1, isautomated => 1, isactive=>0});
#$soapresult = $proxy->call('TestCaseRun.list', {pagesize => 10, page => 0, isautomated => 1});
#$soapresult = $proxy->call('TestCaseRun.lookup_status_id_by_name', 'PASSED');
#$soapresult = $proxy->call('TestCaseRun.lookup_status_name_by_id', 3);
#$soapresult = $proxy->call('TestCaseRun.update', 65104, {status=>3});
#$soapresult = $proxy->call('TestCaseRun.update', [65104,6105,6106] , {status=>3});
#$soapresult = $proxy->call('TestCaseRun.update', 501, 765, 306, 1, {status=>3});
#$soapresult = $proxy->call('TestCaseRun.lookup_status_id_by_name', {name => 'PASSED'});
#$soapresult = $proxy->call('TestCaseRun.lookup_status_name_by_id', {id => 3});
#$soapresult = $proxy->call('TestCaseRun.update', {ids => [9,3], status => 2});
########################
### TestPlan Methods ###
########################
#$soapresult = $proxy->call('TestPlan.add_tag', 74, 'Fish');
#$soapresult = $proxy->call('TestPlan.create', {product_id => 'Bugzilla', name=>'API TEST PLAN', type_id=>'Integration', default_product_version=>'3.0'});
#$soapresult = $proxy->call('TestPlan.get', 74);
#$soapresult = $proxy->call('TestPlan.get_change_history', 74);
#$soapresult = $proxy->call('TestPlan.get_product', 74);
#$soapresult = $proxy->call('TestPlan.get_tags', 74);
#$soapresult = $proxy->call('TestPlan.get_test_cases', 74);
#$soapresult = $proxy->call('TestPlan.get_case_tags', 74);
#$soapresult = $proxy->call('TestPlan.get_test_runs', 74);
#$soapresult = $proxy->call('TestPlan.get_text', 74, 3);
#$soapresult = $proxy->call('TestPlan.list', {product_id=>2, name=> 'selenium'});
#$soapresult = $proxy->call('TestPlan.lookup_type_id_by_name', 'Integration');
#$soapresult = $proxy->call('TestPlan.lookup_type_name_by_id', 11);
#$soapresult = $proxy->call('TestPlan.remove_tag', 74, 'Fish');
#$soapresult = $proxy->call('TestPlan.store_text', 74, 'THIS IS A TEST OF THE PLAN TEXT VIA API');
#$soapresult = $proxy->call('TestPlan.update', 74, {name=>'API UPDATE', type_id=>3, default_product_version=> '2.22'});
#$soapresult = $proxy->call('TestPlan.add_tag', {plan_ids => 74, tags => 'Fish'});
#$soapresult = $proxy->call('TestPlan.create', {product_id => 'TestProduct', name=>'API TEST PLAN', type_id=>'Integration', default_product_version=>'unspecified'});
#$soapresult = $proxy->call('TestPlan.get', {id => 1});
#$soapresult = $proxy->call('TestPlan.get_change_history', {id => 1});
#$soapresult = $proxy->call('TestPlan.get_product', {id => 1});
#$soapresult = $proxy->call('TestPlan.get_tags', {id => 1});
#$soapresult = $proxy->call('TestPlan.get_test_cases', {id => 1});
#$soapresult = $proxy->call('TestPlan.get_case_tags', {id => 1});
#$soapresult = $proxy->call('TestPlan.get_test_runs', {id => 1});
#$soapresult = $proxy->call('TestPlan.get_text', {plan_id => 1, version => 1});
#$soapresult = $proxy->call('TestPlan.list', {product_id=>1, name=> 'selenium'});
#$soapresult = $proxy->call('TestPlan.lookup_type_id_by_name', {name => 'Integration'});
#$soapresult = $proxy->call('TestPlan.lookup_type_name_by_id', {id => 1});
#$soapresult = $proxy->call('TestPlan.remove_tag', {plan_id => 1, tag => 'Fish'});
#$soapresult = $proxy->call('TestPlan.store_text', {plan_id => 1, text => 'THIS IS A TEST OF THE PLAN TEXT VIA API'});
#$soapresult = $proxy->call('TestPlan.update', {id => 1, name=>'API UPDATE', type=>'unit', default_product_version=> 'unspecified'});
#######################
### TestRun Methods ###
#######################
#$soapresult = $proxy->call('TestRun.add_tag', 501, "Fish");
#$soapresult = $proxy->call('TestRun.create', {plan_id => 97, environment_id => 'test', build_id => 'linux', summary => 'API TEST RUN', manager_id => 'ghendricks@novell.com', product_version=>'1.2', status => 1});
#$soapresult = $proxy->call('TestRun.get', 501);
#$soapresult = $proxy->call('TestRun.get_change_history', 501);
#$soapresult = $proxy->call('TestRun.get_completion_report', 501);
#$soapresult = $proxy->call('TestRun.get_tags', 501);
#$soapresult = $proxy->call('TestRun.get_test_case_runs', 501);
#$soapresult = $proxy->call('TestRun.get_test_cases', 501);
#$soapresult = $proxy->call('TestRun.get_case_tags', 501);
#$soapresult = $proxy->call('TestRun.get_test_plan', 501);
#$soapresult = $proxy->call('TestRun.list', {plan => 97});
#$soapresult = $proxy->call('TestRun.remove_tag', 501, 'fish' );
#$soapresult = $proxy->call('TestRun.update', 501, {environment_id => 'test', build_id => 'linux', summary => 'API TEST RUN', manager_id => 'ghendricks@novell.com', product_version=>'1.2'});
#$soapresult = $proxy->call('TestRun.update', 501, { summary => 'API TEST RUN', manager_id => 'ghendricks@novell.com', product_version=>'1.2'});
#$soapresult = $proxy->call('TestRun.update', 501, { status => 0});
#$soapresult = $proxy->call('TestRun.add_cases', {case_ids => [1], run_ids => [1]});
#$soapresult = $proxy->call('TestRun.add_tag', {run_ids => [1], tag => "Fish"});
#$soapresult = $proxy->call('TestRun.create', {plan_id => 1, environment => 'Linux', build => 'Linux', summary => 'API TEST RUN', manager_id => 'ghendricks@novell.com', product_version=>'unspecified', status => 1});
#$soapresult = $proxy->call('TestRun.get', {id => 1});
#$soapresult = $proxy->call('TestRun.get_change_history', {id => 1});
#$soapresult = $proxy->call('TestRun.get_completion_report', {runs => 1});
#$soapresult = $proxy->call('TestRun.get_tags', {id => 1});
#$soapresult = $proxy->call('TestRun.get_test_case_runs', {id => 1, current => 1});
#$soapresult = $proxy->call('TestRun.get_test_cases', {id => 1});
#$soapresult = $proxy->call('TestRun.get_case_tags', {id => 1});
#$soapresult = $proxy->call('TestRun.get_test_plan', {id => 1});
#$soapresult = $proxy->call('TestRun.list', {build => 'Linux'});
#$soapresult = $proxy->call('TestRun.remove_tag', {run_id => 1, tag => 'fish'});
#$soapresult = $proxy->call('TestRun.update', {id =>1, environment_id => 'Linux', build_id => 'linux', summary => 'API TEST RUN', manager_id => 'ghendricks@novell.com', product_version=>'unspecified'});
#$soapresult = $proxy->call('User.lookup_login_by_id', 9 );
#$soapresult = $proxy->call('User.lookup_id_by_login', 'ghendricks@novell.com' );
#$soapresult = $proxy->call('TestopiaUser.lookup_login_by_id', {id => 1} );
#$soapresult = $proxy->call('TestopiaUser.lookup_id_by_login', {login => 'gregaryh@gmail.com'} );
show_results('The results are: ', $soapresult);

View File

@ -1,7 +1,7 @@
<?php
// by Edd Dumbill (C) 1999-2002
// <edd@usefulinc.com>
// $Id: .xmlrpc.inc.php,v 1.2 2010-07-12 21:46:00 mkanat%bugzilla.org Exp $
// $Id: .xmlrpc.inc.php,v 1.3 2010-07-21 17:31:14 mkanat%bugzilla.org Exp $
// Copyright (c) 1999,2000,2002 Edd Dumbill.
// All rights reserved.

View File

@ -1,4 +1,4 @@
#!/usr/bin/perl -w
#!/usr/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
@ -11,15 +11,19 @@
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
# The Original Code is the Bugzilla Testopia System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
# The Initial Developer of the Original Code is Greg Hendricks.
# Portions created by Greg Hendricks are Copyright (C) 2006
# Novell. All Rights Reserved.
#
# Contributor(s): Dawn Endico <endico@mozilla.org>
# David Koenig <dkoenig@novell.com>
# Contributor(s): David Koenig <dkoenig@novell.com>
#################################################################
### THIS FILE IS DEPRECATED IN FAVOR OF tr_import.cgi ###
### and tr_importxml.pl ###
### Please see the POD for Testopia::Impoter ###
#################################################################
use strict;

View File

@ -2525,7 +2525,7 @@ Testopia.TestCaseRun.Info = function(){
loadingText: 'Loading...',
tpl: new Ext.XTemplate('<tpl for=".">', '<div id="notesdiv" style="margin: 5px; padding: 5px; border: 1px solid black;"><pre>{notes}</pre></div>', '</tpl>', '<div class="x-clear"><input id="caserun_append_note_fld" ></div>')
}],
bbar: ['Add a Note: ', {
tbar: ['Add a Note: ', {
xtype: 'textfield',
id: 'caserun_append_note_fld',
listeners: {'afterrender': function(){

View File

@ -1069,6 +1069,15 @@ Testopia.TestPlan.ClonePanel = function(plan){
id: 'copy_runs',
title: 'Copy Test Runs',
collapsed: true,
listeners: {
'expand': function(){
Ext.getCmp('plan_clone_build_chooser').allowBlank = false;
Ext.getCmp('plan_clone_environment_chooser').allowBlank = false;
},
'collapse':function(){
Ext.getCmp('plan_clone_build_chooser').allowBlank = true;
Ext.getCmp('plan_clone_environment_chooser').allowBlank = true;
}},
items: [{
xtype: 'checkbox',
name: 'keep_run_managers',

View File

@ -140,11 +140,9 @@ sub new {
# We want to be able to supply an empty object to the templates for numerous
# lists etc. This is much cleaner than exporting a bunch of subroutines and
# adding them to $vars one by one. Probably just Laziness shining through.
if (ref $param eq 'HASH'){
if (!keys %$param || $param->{PREVALIDATED}){
bless($param, $class);
return $param;
}
if (ref $param eq 'HASH' && !keys %$param){
bless($param, $class);
return $param;
}
unshift @_, $param;

View File

@ -148,13 +148,11 @@ sub new {
# We want to be able to supply an empty object to the templates for numerous
# lists etc. This is much cleaner than exporting a bunch of subroutines and
# adding them to $vars one by one. Probably just Laziness shining through.
if (ref $param eq 'HASH'){
if (!keys %$param || $param->{PREVALIDATED}){
bless($param, $class);
return $param;
}
if (ref $param eq 'HASH' && !keys %$param){
bless($param, $class);
return $param;
}
unshift @_, $param;
my $self = $class->SUPER::new(@_);

View File

@ -124,13 +124,11 @@ sub new {
# We want to be able to supply an empty object to the templates for numerous
# lists etc. This is much cleaner than exporting a bunch of subroutines and
# adding them to $vars one by one. Probably just Laziness shining through.
if (ref $param eq 'HASH'){
if (!keys %$param || $param->{PREVALIDATED}){
bless($param, $class);
return $param;
}
if (ref $param eq 'HASH' && !keys %$param){
bless($param, $class);
return $param;
}
unshift @_, $param;
my $self = $class->SUPER::new(@_);

View File

@ -53,10 +53,10 @@ sub user_visible_products {
$query .= "UNION (SELECT id, products.name AS pname FROM products ".
"INNER JOIN test_plans ON products.id = test_plans.product_id ".
"INNER JOIN test_plan_permissions ON test_plan_permissions.plan_id = test_plans.plan_id ".
"WHERE test_plan_permissions.userid = ?)";
"WHERE test_plan_permissions.userid = ? AND products.classification_id = ?)";
$query .= "ORDER BY pname ";
my $product_ids = $dbh->selectcol_arrayref($query, undef, $self->id, Bugzilla->user->id);
my $product_ids = $dbh->selectcol_arrayref($query, undef, $self->id, Bugzilla->user->id, $self->id);
my @products;
foreach my $product_id (@$product_ids) {

View File

@ -174,13 +174,11 @@ sub new {
# We want to be able to supply an empty object to the templates for numerous
# lists etc. This is much cleaner than exporting a bunch of subroutines and
# adding them to $vars one by one. Probably just Laziness shining through.
if (ref $param eq 'HASH'){
if (!keys %$param || $param->{PREVALIDATED}){
bless($param, $class);
return $param;
}
if (ref $param eq 'HASH' && !keys %$param){
bless($param, $class);
return $param;
}
unshift @_, $param;
my $self = $class->SUPER::new(@_);
@ -216,8 +214,12 @@ my $modified_environment_structure = 0;
sub create_full {
my $self = shift;
# print STDERR Data::Dumper::Dumper(\@_);
my ($env_basename, $prod_id, $environment) = @_;
trick_taint($env_basename);
detaint_natural($prod_id);
# first, get ALL rows to add to test_environment_map table
# and store them in @environment_map array
foreach my $key (keys(%{$environment})){
@ -243,14 +245,17 @@ sub create_full {
foreach my $hash (@environment_map) {
my $env_id_conditions = "environment_id = " . pop @envmatch;
foreach(@envmatch){$env_id_conditions .= " OR environment_id = $_";}
trick_taint($hash->{value_selected});
@envmatch = @{$dbh->selectcol_arrayref(
"SELECT environment_id
FROM test_environment_map
WHERE ( $env_id_conditions ) AND
property_id = $hash->{prop_id} AND
element_id = $hash->{elem_id} AND
value_selected = '$hash->{value_selected}'")};
property_id = ? AND
element_id = ? AND
value_selected = ?",
undef, ($hash->{prop_id},
$hash->{elem_id},
$hash->{value_selected}))};
last if (!scalar(@envmatch));
}
@ -299,6 +304,7 @@ sub _parseElementsRecursively {
my $elem = Bugzilla::Extension::Testopia::Environment::Element->new({});
# get exising element OR create new one
my ($elem_id) = $elem->check_element($key, $callerid);
print STDERR "ELEMENTID $elem_id";
if(!$elem_id){
$elem->{'env_category_id'} = ($callertype eq 'category') ? $callerid : $categoryid;
$elem->{'name'} = $key;
@ -310,6 +316,7 @@ sub _parseElementsRecursively {
}
_parseElementsRecursively($hash->{$key}, $elem_id, 'element', $categoryid);
} else {
trick_taint($hash->{$key});
require Bugzilla::Extension::Testopia::Environment::Property;
my $prop = Bugzilla::Extension::Testopia::Environment::Property->new({});
my ($prop_id) = $prop->check_property($key, $callerid);
@ -620,6 +627,7 @@ sub store_property_value {
return 0 if ($self->check_value_selected($prop_id, $elem_id, $value_selected));
my $dbh = Bugzilla->dbh;
trick_taint $value_selected;
$dbh->do("INSERT INTO test_environment_map (environment_id,property_id,element_id,value_selected)
VALUES (?,?,?,?)",undef, ($self->{'environment_id'}, $prop_id, $elem_id,$value_selected));
return 1;

View File

@ -222,7 +222,7 @@ Serializes the new property to the database
sub store {
my $self = shift;
# Exclude the auto-incremented field from the column list.
my $columns = join( ", ", grep { $_ ne 'property_id' } DB_COLUMNS );
my $timestamp = Bugzilla::Extension::Testopia::Util::get_time_stamp();

View File

@ -418,3 +418,19 @@ sub parse {
}
1;
__END__
=head1 NAME
Bugzilla::Extension::Testopia::Importer
=head1 DESCRIPTION
Importer is responsible for importing test plans, cases, and runs from XML.
=head1 SEE ALSO
See tr_importxml.pl for usage.
See testopia.xsd for format

View File

@ -470,17 +470,18 @@ sub new {
# We want to be able to supply an empty object to the templates for numerous
# lists etc. This is much cleaner than exporting a bunch of subroutines and
# adding them to $vars one by one. Probably just Laziness shining through.
if (ref $param eq 'HASH'){
if (ref $param eq 'HASH' && !keys %$param){
bless($param, $class);
return $param;
}
if (!defined $param || (!ref($param) && $param !~ /^\d+$/)) {
$param = { name => $param };
}
unshift @_, $param;
my $self = $class->SUPER::new(@_);
return $self;
}
@ -579,6 +580,7 @@ sub update {
sub lookup_status {
my ($id) = @_;
my $dbh = Bugzilla->dbh;
trick_taint($id);
my ($value) = $dbh->selectrow_array(
"SELECT name
FROM test_case_status
@ -589,6 +591,7 @@ sub lookup_status {
sub lookup_status_by_name {
my ($name) = @_;
trick_taint($name);
my $dbh = Bugzilla->dbh;
my ($value) = $dbh->selectrow_array(
"SELECT case_status_id
@ -601,6 +604,7 @@ sub lookup_status_by_name {
sub lookup_category {
my ($id) = @_;
my $dbh = Bugzilla->dbh;
trick_taint($id);
my ($value) = $dbh->selectrow_array(
"SELECT name
FROM test_case_categories
@ -611,7 +615,7 @@ sub lookup_category {
sub lookup_category_by_name {
my ($name) = @_;
trick_taint $name;
trick_taint($name);
my $dbh = Bugzilla->dbh;
my ($value) = $dbh->selectrow_array(
"SELECT category_id
@ -624,6 +628,7 @@ sub lookup_category_by_name {
sub lookup_priority {
my ($id) = @_;
my $dbh = Bugzilla->dbh;
trick_taint($id);
my ($value) = $dbh->selectrow_array(
"SELECT value
FROM priority
@ -635,6 +640,7 @@ sub lookup_priority {
sub lookup_priority_by_value {
my ($value) = @_;
my $dbh = Bugzilla->dbh;
trick_taint($value);
my ($id) = $dbh->selectrow_array(
"SELECT id
FROM priority
@ -646,6 +652,7 @@ sub lookup_priority_by_value {
sub lookup_default_tester {
my ($id) = @_;
my $dbh = Bugzilla->dbh;
trick_taint($id);
my ($value) = $dbh->selectrow_array(
"SELECT login_name
FROM profiles
@ -1216,6 +1223,7 @@ sub store_text {
trick_taint($effect) if $effect;
trick_taint($breakdown) if $breakdown;
trick_taint($setup) if $setup;
detaint_natural($key);
my $version = $reset_version ? 0 : $self->version || 0;
$dbh->do("INSERT INTO test_case_texts
@ -1275,6 +1283,9 @@ sub unlink_plan {
my $self = shift;
my $dbh = Bugzilla->dbh;
my ($plan_id) = @_;
detaint_natural($plan_id);
my $plan = Bugzilla::Extension::Testopia::TestPlan->new($plan_id);
if (scalar @{$self->plans} == 1){

View File

@ -180,21 +180,13 @@ sub new {
my ($param, $case_id, $build_id, $env_id) = (@_);
my $dbh = Bugzilla->dbh;
# We want to be able to supply an empty object to the templates for numerous
# lists etc. This is much cleaner than exporting a bunch of subroutines and
# adding them to $vars one by one. Probably just Laziness shining through.
if (ref $param eq 'HASH'){
if (!keys %$param || $param->{PREVALIDATED}){
bless($param, $class);
return $param;
}
}
elsif ($case_id && detaint_natural($case_id)
if ($case_id && detaint_natural($case_id)
&& $build_id && detaint_natural($build_id)
&& $env_id && detaint_natural($env_id)){
my $run_id = $param;
detaint_natural($case_id) || return undef;
detaint_natural($run_id) || return undef;
($param) = $dbh->selectrow_array(
"SELECT case_run_id FROM test_case_runs
WHERE case_id = ?
@ -205,9 +197,17 @@ sub new {
ThrowUserError('invalid-test-id-non-existent', {type => 'case_run'}) unless $param;
}
# We want to be able to supply an empty object to the templates for numerous
# lists etc. This is much cleaner than exporting a bunch of subroutines and
# adding them to $vars one by one. Probably just Laziness shining through.
if (ref $param eq 'HASH' && !keys %$param){
bless($param, $class);
return $param;
}
unshift @_, $param;
my $self = $class->SUPER::new(@_);
return $self;
}
@ -1219,7 +1219,7 @@ Returns the id of the status name passed.
sub lookup_status_by_name {
my ($name) = @_;
my $dbh = Bugzilla->dbh;
trick_taint($name);
my ($value) = $dbh->selectrow_array(
"SELECT case_run_status_id
FROM test_case_run_status

View File

@ -194,18 +194,14 @@ sub new {
# We want to be able to supply an empty object to the templates for numerous
# lists etc. This is much cleaner than exporting a bunch of subroutines and
# adding them to $vars one by one. Probably just Laziness shining through.
if (ref $param eq 'HASH'){
if (keys %$param){
bless($param, $class);
return $param;
}
if (ref $param eq 'HASH' && !keys %$param){
bless($param, $class);
return $param;
}
unshift @_, $param;
my $self = $class->SUPER::new(@_);
return $self;
}
@ -295,6 +291,7 @@ sub store_text {
}
$text ||= '';
trick_taint($text);
detaint_natural($key);
my $version = $self->version || 0;
$dbh->do("INSERT INTO test_plan_texts
@ -674,6 +671,7 @@ Takes an ID of the type field and returns the value
sub lookup_type {
my ($id) = @_;
my $dbh = Bugzilla->dbh;
detaint_natural($id);
my ($value) = $dbh->selectrow_array(
"SELECT name
FROM test_plan_types
@ -691,6 +689,7 @@ Returns the id of the type name passed.
sub lookup_type_by_name {
my ($name) = @_;
my $dbh = Bugzilla->dbh;
trick_taint($name);
my ($value) = $dbh->selectrow_array(
"SELECT type_id
FROM test_plan_types

View File

@ -241,17 +241,17 @@ sub new {
my $class = ref($invocant) || $invocant;
my $param = shift;
unshift @_, $param;
my $self = $class->SUPER::new(@_);
# We want to be able to supply an empty object to the templates for numerous
# lists etc. This is much cleaner than exporting a bunch of subroutines and
# adding them to $vars one by one. Probably just Laziness shining through.
if (ref $param eq 'HASH'){
if (!$self && ref $param eq 'HASH'){
bless($param, $class);
return $param;
}
unshift @_, $param;
my $self = $class->SUPER::new(@_);
return $self;
}
@ -937,7 +937,7 @@ sub get_case_tags {
my $tags = $dbh->selectcol_arrayref(
"SELECT DISTINCT test_tags.tag_id FROM test_case_tags
INNER JOIN test_tags ON test_case_tags.tag_id = test_tags.tag_id
INNER JOIN test_case_runss on test_case_runss.case_id = test_case_tags.case_id
INNER JOIN test_case_runs on test_case_runs.case_id = test_case_tags.case_id
WHERE test_case_runs.run_id = ?", undef, $self->id);
my @tags;
foreach my $id (@$tags){

View File

@ -34,14 +34,19 @@ use Bugzilla::Extension::Testopia::Product;
sub get {
my $self = shift;
my ($build_id) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{id} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
# Result is a build object hash
my $build = new Bugzilla::Extension::Testopia::Build($build_id);
my $build = new Bugzilla::Extension::Testopia::Build($params);
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $build_id}) unless $build;
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $params->{id}}) unless $build->{build_id};
ThrowUserError('testopia-read-only', {'object' => $build->product}) unless $build->product->canedit;
$build->run_count();
@ -51,21 +56,29 @@ sub get {
sub check_build {
my $self = shift;
my ($name, $product) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{name} = shift;
$params->{product} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
if ($product =~ /^\d+$/){
$product = Bugzilla::Extension::Testopia::Product->new($product);
my $product;
if ($params->{product} =~ /^\d+$/){
$product = Bugzilla::Extension::Testopia::Product->new($params->{product});
}
else {
$product = Bugzilla::Product::check_product($product);
$product = Bugzilla::Product::check_product($params->{product});
$product = Bugzilla::Extension::Testopia::Product->new($product->id);
}
ThrowUserError('testopia-read-only', {'object' => $product}) unless $product->canedit;
return Bugzilla::Extension::Testopia::Build::check_build($name, $product, "THROWERROR");
return Bugzilla::Extension::Testopia::Build::check_build($params->{name}, $product, "THROWERROR");
}
sub create{
@ -101,12 +114,17 @@ sub create{
sub update{
my $self = shift;
my ($id, $new_values) = @_;
my ($new_values) = @_;
if(!ref $new_values){
$new_values = $_[1];
$new_values->{id} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
my $build = new Bugzilla::Extension::Testopia::Build($id);
ThrowUserError("invalid-test-id-non-existent", {'id' => $id, 'type' => 'Build'}) unless $build;
my $build = new Bugzilla::Extension::Testopia::Build($new_values->{id});
ThrowUserError("invalid-test-id-non-existent", {'id' => $new_values->{id}, 'type' => 'Build'}) unless $build->{build_id};
ThrowUserError('testopia-read-only', {'object' => $build->product}) unless $build->product->canedit;
$build->set_name($new_values->{'name'}) if $new_values->{'name'};
@ -122,14 +140,19 @@ sub update{
# DEPRECATED use Build::get instead
sub lookup_name_by_id {
my $self = shift;
my ($build_id) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{id} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
die "Invalid Build ID"
unless defined $build_id && length($build_id) > 0 && $build_id > 0;
unless defined $params->{id} && length($params->{id}) > 0 && $params->{id} > 0;
my $build = new Bugzilla::Extension::Testopia::Build($build_id);
my $build = new Bugzilla::Extension::Testopia::Build($params->{id});
ThrowUserError('testopia-read-only', {'object' => $build->product}) unless $build->product->canedit;
my $result = defined $build ? $build->name : '';
@ -138,20 +161,20 @@ sub lookup_name_by_id {
return $result;
}
# DEPRECATED use Build::check_build($name, $product) instead
sub lookup_id_by_name {
return { ERROR => 'This method is considered harmful and has been deprecated. Please use Build::check_build instead'};
}
sub get_runs {
my $self = shift;
my ($build_id) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{id} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
my $build = new Bugzilla::Extension::Testopia::Build($build_id);
my $build = new Bugzilla::Extension::Testopia::Build($params);
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $build_id}) unless $build;
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $params->{id}}) unless $build->{build_id};
ThrowUserError('testopia-read-only', {'object' => $build}) unless $build->product->canview;
# Result is list of test runs for the given build
@ -160,13 +183,18 @@ sub get_runs {
sub get_caseruns {
my $self = shift;
my ($build_id) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{id} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
my $build = new Bugzilla::Extension::Testopia::Build($build_id);
my $build = new Bugzilla::Extension::Testopia::Build($params);
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $build_id}) unless $build;
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $params->{id}}) unless $build->{build_id};
ThrowUserError('testopia-read-only', {'object' => $build}) unless $build->product->canview;
# Result is list of test runs for the given build
@ -187,13 +215,19 @@ Bugzilla::Webservice
=head1 DESCRIPTION
Provides methods for automated scripts to manipulate Testopia Builds
Provides methods for automated scripts to manipulate Testopia Builds.
It is important that you read the documentation for L<Bugzilla::WebService>
as this documentation assumes you are familiar with XMLRPC from Bugzilla.
NOTE: In most cases where and id is required, a name attribute can be used instead
provided it is unique. For example, Build.get({id => integer}) can substitute
Build.get({name => string})
=head1 METHODS
=over
=item C<check_build($name, $product)>
=item C<check_build>
Description: Looks up and returns a build by name.
@ -204,7 +238,7 @@ Provides methods for automated scripts to manipulate Testopia Builds
Returns: Hash: Matching Build object hash or error if not found.
=item C<create($values)>
=item C<create>
Description: Creates a new build object and stores it in the database
@ -222,7 +256,7 @@ Provides methods for automated scripts to manipulate Testopia Builds
Returns: The newly created object hash.
=item C<get($id)>
=item C<get>
Description: Used to load an existing build from the database.
@ -230,7 +264,7 @@ Provides methods for automated scripts to manipulate Testopia Builds
Returns: A blessed Bugzilla::Extension::Testopia::Build object hash
=item C<get_caseruns($id)>
=item C<get_caseruns>
Description: Returns the list of case-runs that this Build is used in.
@ -238,7 +272,7 @@ Provides methods for automated scripts to manipulate Testopia Builds
Returns: Array: List of case-run object hashes.
=item C<get_runs($id)>
=item C<get_runs>
Description: Returns the list of runs that this Build is used in.
@ -246,26 +280,23 @@ Provides methods for automated scripts to manipulate Testopia Builds
Returns: Array: List of run object hashes.
=item C<lookup_id_by_name> B<DEPRECATED - CONSIDERED HARMFUL> Use Build::check_build instead
=item C<lookup_name_by_id> B<DEPRECATED> Use Build::get instead
=item C<update($id, $values)>
=item C<update>
Description: Updates the fields of the selected build or builds.
Params: $id - Integer: A single build ID.
$values - Hash of keys matching Build fields and the new values
Params: $values - Hash of keys matching Build fields and the new values
to set each field to.
+-------------+----------------+
| Field | Type |
+-------------+----------------+
| name | String |
| milestone | String |
| description | String |
| isactive | Boolean |
+-------------+----------------+
The id field is used to lookup the build and is read only.
+--------------+----------------+
| Field | Type |
+--------------+----------------+
| id (readonly)| Integer |
| name | String |
| milestone | String |
| description | String |
| isactive | Boolean |
+--------------+----------------+
Returns: Hash: The updated Build object hash.
@ -273,8 +304,13 @@ Provides methods for automated scripts to manipulate Testopia Builds
=head1 SEE ALSO
L<Bugzilla::Extension::Testopia::Build>
L<Bugzilla::Webservice>
=over
=item L<Bugzilla::Extension::Testopia::Build>
=item L<Bugzilla::Webservice>
=back
=head1 AUTHOR

View File

@ -30,18 +30,24 @@ use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Extension::Testopia::Environment;
use Bugzilla::Extension::Testopia::Product;
use Bugzilla::Extension::Testopia::Search;
use Bugzilla::Extension::Testopia::Table;
sub get {
my $self = shift;
my ($environment_id) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{id} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
my $environment = new Bugzilla::Extension::Testopia::Environment($environment_id);
my $environment = new Bugzilla::Extension::Testopia::Environment($params);
ThrowUserError('invalid-test-id-non-existent', {type => 'Environment', id => $environment_id}) unless $environment;
ThrowUserError('invalid-test-id-non-existent', {type => 'Environment', id => $params}) unless $environment->{environment_id};
ThrowUserError('testopia-read-only', {'object' => $environment}) unless $environment->canview;
#Result is a environment hash map
@ -50,21 +56,28 @@ sub get {
sub check_environment {
my $self = shift;
my ($name, $product) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{name} = shift;
$params->{product} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
if ($product =~ /^\d+$/){
$product = Bugzilla::Extension::Testopia::Product->new($product);
my $product;
if ($params->{product} =~ /^\d+$/){
$product = Bugzilla::Extension::Testopia::Product->new($params->{product});
}
else {
$product = Bugzilla::Product::check_product($product);
$product = Bugzilla::Product::check_product($params->{product});
$product = Bugzilla::Extension::Testopia::Product->new($product->id);
}
ThrowUserError('testopia-read-only', {'object' => $product}) unless $product->canedit;
return Bugzilla::Extension::Testopia::Environment::check_environment($name, $product, 'THROWERROR');
return Bugzilla::Extension::Testopia::Environment::check_environment($params->{name}, $product, 'THROWERROR');
}
sub list {
@ -82,7 +95,7 @@ sub list {
my $search = Bugzilla::Extension::Testopia::Search->new($cgi);
# Result is an array of environment hash maps
return Bugzilla::Extension::Testopia::Table->new('environment', 'tr_xmlrpc.cgi',$cgi,undef, $search->query())->list();
return Bugzilla::Extension::Testopia::Table->new('environment', 'xmlrpc.cgi',$cgi,undef, $search->query())->list();
}
@ -119,33 +132,40 @@ sub create {
sub create_full {
my $self = shift;
my ($env_basename, $product, $environment) = @_;
my ($params) = @_;
Bugzilla->login(LOGIN_REQUIRED);
if ($product =~ /^\d+$/){
$product = Bugzilla::Extension::Testopia::Product->new($product);
my $product;
if ($params->{product} =~ /^\d+$/){
$product = Bugzilla::Extension::Testopia::Product->new($params->{product});
}
else {
$product = Bugzilla::Product::check_product($product);
$product = Bugzilla::Product::check_product($params->{product});
$product = Bugzilla::Extension::Testopia::Product->new($product->id);
}
ThrowUserError('testopia-read-only', {'object' => $product}) unless $product->canedit;
my $env_id = Bugzilla::Extension::Testopia::Environment->create_full($env_basename, $product->id, $environment);
my $env_id = Bugzilla::Extension::Testopia::Environment->create_full($params->{name}, $product->id, $params->{environment});
return $env_id;
}
sub update {
my $self = shift;
my ($environment_id, $new_values) = @_;
my ($new_values) = @_;
Bugzilla->login(LOGIN_REQUIRED);
my $environment = new Bugzilla::Extension::Testopia::Environment($environment_id);
if(!ref $new_values){
$new_values = $_[1];
$new_values->{id} = $_[0];
}
ThrowUserError('invalid-test-id-non-existent', {type => 'Environment', id => $environment_id}) unless $environment;
Bugzilla->login(LOGIN_REQUIRED);
my $environment = new Bugzilla::Extension::Testopia::Environment($new_values);
ThrowUserError('invalid-test-id-non-existent', {type => 'Environment', id => $new_values->{id}}) unless $environment->{environment_id};
ThrowUserError('testopia-read-only', {'object' => $environment}) unless $environment->canedit;
$environment->set_name($new_values->{'name'}) if $new_values->{'name'};
@ -159,13 +179,18 @@ sub update {
sub get_runs {
my $self = shift;
my ($environment_id) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{id} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
my $environment = new Bugzilla::Extension::Testopia::Environment($environment_id);
my $environment = new Bugzilla::Extension::Testopia::Environment($params);
ThrowUserError('invalid-test-id-non-existent', {type => 'Environment', id => $environment_id}) unless $environment;
ThrowUserError('invalid-test-id-non-existent', {type => 'Environment', id => $params->{id}}) unless $environment->{environment_id};
ThrowUserError('testopia-read-only', {'object' => $environment}) unless $environment->canview;
# Result is list of test runs for the given environment
@ -174,13 +199,18 @@ sub get_runs {
sub get_caseruns {
my $self = shift;
my ($environment_id) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{id} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
my $environment = new Bugzilla::Extension::Testopia::Environment($environment_id);
my $environment = new Bugzilla::Extension::Testopia::Environment($params);
ThrowUserError('invalid-test-id-non-existent', {type => 'Environment', id => $environment_id}) unless $environment;
ThrowUserError('invalid-test-id-non-existent', {type => 'Environment', id => $params->{id}}) unless $environment->{environment_id};
ThrowUserError('testopia-read-only', {'object' => $environment}) unless $environment->canview;
# Result is list of test runs for the given environment
@ -206,7 +236,7 @@ Provides methods for automated scripts to manipulate Testopia Environments
=over
=item C<check_environment($name, $product)>
=item C<check_environment>
Description: Looks up and returns an environment by name.
@ -217,7 +247,7 @@ Provides methods for automated scripts to manipulate Testopia Environments
Returns: Hash: Matching Environment object hash or error if not found.
=item C<create($values)>
=item C<create>
Description: Creates a new environment object and stores it in the database
@ -233,7 +263,7 @@ Provides methods for automated scripts to manipulate Testopia Environments
Returns: The newly created object hash.
=item C<create_full($basename, $product, $envhash)>
=item C<create_full>
Description: When an environment starting with $basename does not exist yet
exactly matching $envhash, creates a new environment object, and any new
@ -316,7 +346,7 @@ Harddrives => {
Returns: The environment id of the newly created or matching environment.
=item C<get($id)>
=item C<get>
Description: Used to load an existing Environment from the database.
@ -324,7 +354,7 @@ Harddrives => {
Returns: A blessed Bugzilla::Extension::Testopia::Environment object hash
=item C<get_caseruns($id)>
=item C<get_caseruns>
Description: Returns the list of case-runs that this Environment is used in.
@ -332,7 +362,7 @@ Harddrives => {
Returns: Array: List of case-run object hashes.
=item C<get_runs($id)>
=item C<get_runs>
Description: Returns the list of runs that this Environment is used in.
@ -340,7 +370,7 @@ Harddrives => {
Returns: Array: List of run object hashes.
=item C<list($query)>
=item C<list>
Description: Performs a search and returns the resulting list of Environments
@ -359,20 +389,21 @@ Harddrives => {
Returns: Array: Matching Environments are retuned in a list of hashes.
=item C<update($ids, $values)>
=item C<update>
Description: Updates the fields of the selected environment or environments.
Params: $ids - Integer A single environment ID.
$values - Hash of keys matching Environment fields and the new values
Params: $values - Hash of keys matching Environment fields and the new values
to set each field to.
+-------------+----------------+
| Field | Type |
+-------------+----------------+
| name | String |
| isactive | Boolean |
+-------------+----------------+
The id field is used to lookup the environment and is read only.
+--------------+----------------+
| Field | Type |
+--------------+----------------+
| id (readonly)| String |
| name | String |
| isactive | Boolean |
+--------------+----------------+
Returns: Hash: The updated environment object hash.

View File

@ -32,18 +32,13 @@ use Bugzilla::Constants;
use Bugzilla::Extension::Testopia::Product;
sub _validate {
my ($product) = @_;
my ($params) = @_;
Bugzilla->login(LOGIN_REQUIRED);
if ($product =~ /^\d+$/){
$product = Bugzilla::Extension::Testopia::Product->new($product);
}
else {
$product = Bugzilla::Product::check_product($product);
$product = Bugzilla::Extension::Testopia::Product->new($product->id);
}
my $product = Bugzilla::Extension::Testopia::Product->new($params);
ThrowUserError('invalid-test-id-non-existent', {type => 'Product', id => $product}) unless $product;
ThrowUserError('invalid-test-id-non-existent', {type => 'Product', id => $params}) unless $product;
ThrowUserError('testopia-permission-denied', {'object' => $product}) if $product && !$product->canedit;
return $product;
@ -75,37 +70,55 @@ sub check_product {
sub check_category {
my $self = shift;
my ($name, $product) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{name} = shift;
$params->{product} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
$product = _validate($product);
my $product = _validate($params->{product});
ThrowUserError('testopia-read-only', {'object' => $product}) unless $product->canedit;
require Bugzilla::Extension::Testopia::Category;
return Bugzilla::Extension::Testopia::Category->new(Testopia::Category::check_case_category($name, $product));
return Bugzilla::Extension::Testopia::Category->new(Bugzilla::Extension::Testopia::Category::check_case_category($params));
}
sub check_component {
my $self = shift;
my ($name, $product) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$params->{name} = shift;
$params->{product} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
$product = _validate($product);
my $product = _validate($params->{product});
ThrowUserError('testopia-read-only', {'object' => $product}) unless $product->canedit;
ThrowUserError('testopia-read-only', {'object' => $params->{product}}) unless $product->canedit;
require Bugzilla::Component;
return Bugzilla::Component->check({product => $product, name => $name});
return Bugzilla::Component->check($params);
}
sub get_builds {
my $self = shift;
my ($product, $active) = @_;
my ($params) = @_;
$product = _validate($product);
if (!ref $params){
$params = {};
$_[0] =~ /^\d+$/ ? $params->{id} = $_[0] : $params->{name} = $_[0];
$params->{active} = $_[1];
}
return $product->builds($active);
my $product = _validate($params);
return $product->builds($params->{active});
}
@ -129,14 +142,28 @@ sub get_category {
sub get_component {
my $self = shift;
my ($id) = @_;
my ($params) = @_;
if (!ref $params){
$params = {};
$_[0] =~ /^\d+$/ ? $params->{id} = $_[0] : $params->{name} = $_[0];
$params->{product} = $_[1];
}
Bugzilla->login(LOGIN_REQUIRED);
require Bugzilla::Component;
my $component = Bugzilla::Component->new($id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Component', id => $id}) unless $component;
my $component;
if ($params->{product}){
$params->{product} = Bugzilla::Product->new({name => $params->{product}});
$component = Bugzilla::Component->new($params);
}
else {
$component = Bugzilla::Component->new($params->{id});
}
ThrowUserError('invalid-test-id-non-existent', {type => 'Component', id => $params}) unless $component;
my $product = Bugzilla::Extension::Testopia::Product->new($component->product_id);
@ -227,13 +254,6 @@ sub get_versions {
}
sub lookup_name_by_id {
return {ERROR=> 'This method id deprecated. Use Product::get instead.'};
}
sub lookup_id_by_name {
return {ERROR=> 'This method id deprecated. Use Product::check_product instead.'};
}
1;
__END__
@ -250,11 +270,16 @@ Bugzilla::Webservice
Provides methods for automated scripts to expose Testopia Product data.
NOTE: In most cases where and id is required, a name attribute can be used instead
provided it is unique. For example, Build.get({id => integer}) can substitute
Build.get({name => string})
=head1 METHODS
=over
=item C<check_category($name, $product)>
=item C<check_category>
Description: Looks up and returns a category by name.
@ -265,7 +290,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Hash: Matching Category object hash or error if not found.
=item C<check_component($name, $product)>
=item C<check_component>
Description: Looks up and returns a component by name.
@ -276,7 +301,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Hash: Matching component object hash or error if not found.
=item C<check_product($name, $product)>
=item C<check_product>
Description: Looks up and returns a validated product.
@ -284,7 +309,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Hash: Matching Product object hash or error if not found.
=item C<get($id)>
=item C<get>
Description: Used to load an existing product from the database.
@ -292,7 +317,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: A blessed Bugzilla::Extension::Testopia::Product object hash
=item C<get_builds($product, $active)>
=item C<get_builds>
Description: Get the list of builds associated with this product.
@ -303,7 +328,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Array: Returns an array of Build objects.
=item C<get_cases($product)>
=item C<get_cases>
Description: Get the list of cases associated with this product.
@ -313,7 +338,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Array: Returns an array of TestCase objects.
=item C<get_categories($product)>
=item C<get_categories>
Description: Get the list of categories associated with this product.
@ -323,7 +348,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Array: Returns an array of Case Category objects.
=item C<get_category($id)>
=item C<get_category>
Description: Get the category matching the given id.
@ -331,7 +356,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Hash: Category object hash.
=item C<get_component($id)>
=item C<get_component>
Description: Get the component matching the given id.
@ -339,7 +364,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Hash: Component object hash.
=item C<get_components($product)>
=item C<get_components>
Description: Get the list of components associated with this product.
@ -349,7 +374,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Array: Returns an array of Component objects.
=item C<get_environments($product)>
=item C<get_environments>
Description: Get the list of environments associated with this product.
@ -359,7 +384,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Array: Returns an array of Environment objects.
=item C<get_milestones($product)>
=item C<get_milestones>
Description: Get the list of milestones associated with this product.
@ -369,7 +394,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Array: Returns an array of Milestone objects.
=item C<get_plans($product)>
=item C<get_plans>
Description: Get the list of plans associated with this product.
@ -379,7 +404,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Array: Returns an array of Test Plan objects.
=item C<get_runs($product)>
=item C<get_runs>
Description: Get the list of runs associated with this product.
@ -389,7 +414,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Array: Returns an array of Test Run objects.
=item C<get_tags($product)>
=item C<get_tags>
Description: Get the list of tags associated with this product.
@ -399,7 +424,7 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Array: Returns an array of Tags objects.
=item C<get_versions($product)>
=item C<get_versions>
Description: Get the list of versions associated with this product.
@ -409,10 +434,6 @@ Provides methods for automated scripts to expose Testopia Product data.
Returns: Array: Returns an array of Version objects.
=item C<lookup_name_by_id> B<DEPRECATED> Use Product::get instead
=item C<lookup_id_by_name> B<DEPRECATED - CONSIDERED HARMFUL> Use Product::check_product instead
=back
=head1 SEE ALSO

View File

@ -43,7 +43,7 @@ sub get {
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case->{case_id};
ThrowUserError('testopia-permission-denied', {'object' => $case}) unless $case->canview;
$case->text();
@ -125,7 +125,7 @@ sub create {
eval{
foreach my $id (@plan_ids){
my $plan = Bugzilla::Extension::Testopia::TestPlan->new($id);
ThrowUserError("invalid-test-id-non-existent", {'id' => $id, 'type' => 'Plan'}) unless $plan;
ThrowUserError("invalid-test-id-non-existent", {'id' => $id, 'type' => 'Plan'}) unless $plan->{plan_id};
ThrowUserError("testopia-create-denied", {'object' => 'Test Case', 'plan' => $plan}) unless $plan->canedit;
push @plans, $plan;
}
@ -187,11 +187,16 @@ sub create {
sub update {
my $self = shift;
my ($ids, $new_values) = @_;
my ($new_values) = @_;
if(ref $new_values ne 'HASH'){
$new_values = $_[1];
$new_values->{ids} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($new_values->{ids});
my @dependson;
if (ref $new_values->{'dependson'} eq 'ARRAY'){
@ -207,7 +212,7 @@ sub update {
my @cases;
foreach my $id (@ids){
my $case = new Bugzilla::Extension::Testopia::TestCase($id);
unless ($case){
unless ($case->{case_id}){
ThrowUserError("invalid-test-id-non-existent", {'id' => $id, 'type' => 'Case'}) if scalar @ids == 1;
push @cases, {ERROR => "TestCase $id does not exist"};
next;
@ -260,36 +265,52 @@ sub update {
sub get_text {
my $self = shift;
my ($case_id, $version) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_id} = shift;
$params->{version} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
my $case = new Bugzilla::Extension::Testopia::TestCase($params->{case_id});
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $params->{case_id}}) unless $case->{case_id};
ThrowUserError('testopia-permission-denied', {'object' => $case}) unless $case->canview;
#Result is the latest test case doc hash map
return $case->text($version);
return $case->text($params->{version});
}
sub store_text {
my $self = shift;
my ($case_id, $action, $effect, $setup, $breakdown, $author_id,) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_id} = shift;
$params->{action} = shift;
$params->{effect} = shift;
$params->{setup} = shift;
$params->{breakdown} = shift;
$params->{author_id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
my $case = new Bugzilla::Extension::Testopia::TestCase($params->{case_id});
$author_id ||= Bugzilla->user->id;
if ($author_id !~ /^\d+$/){
$author_id = Bugzilla::User::login_to_id($author_id, "THROWERROR");
$params->{author_id} ||= Bugzilla->user->id;
if ($params->{author_id} !~ /^\d+$/){
$params->{author_id} = Bugzilla::User::login_to_id($params->{author_id}, "THROWERROR");
}
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $params->{case_id}}) unless $case->{case_id};
ThrowUserError('testopia-read-only', {'object' => $case}) unless $case->canedit;
my $version = $case->store_text($case_id, $author_id, $action, $effect, $setup, $breakdown);
my $version = $case->store_text($params->{case_id}, $params->{author_id}, $params->{action}, $params->{effect}, $params->{setup}, $params->{breakdown});
# Result is new test case doc version on success, otherwise an exception will be thrown
return $version;
@ -303,7 +324,7 @@ sub get_plans {
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case->{case_id};
ThrowUserError('testopia-permission-denied', {'object' => $case}) unless $case->canview;
return $case->plans();
@ -311,15 +332,21 @@ sub get_plans {
sub attach_bug {
my $self = shift;
my ($case_ids, $bug_ids) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_ids} = shift;
$params->{bug_ids} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($case_ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($params->{case_ids});
my @results;
foreach my $id (@ids){
my $case = new Bugzilla::Extension::Testopia::TestCase($id);
unless ($case){
unless ($case->{case_id}){
push @results, {ERROR => "TestCase $id does not exist"};
next;
}
@ -328,7 +355,7 @@ sub attach_bug {
next;
}
eval {
$case->attach_bug($bug_ids);
$case->attach_bug($params->{bug_ids});
};
if ($@){
push @results, {ERROR => $@};
@ -340,16 +367,22 @@ sub attach_bug {
sub detach_bug {
my $self = shift;
my ($case_id, $bugids) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_id} = shift;
$params->{bug_ids} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
my $case = new Bugzilla::Extension::Testopia::TestCase($params->{case_id});
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $params->{case_id}}) unless $case->{case_id};
ThrowUserError('testopia-read-only', {'object' => $case}) unless $case->canedit;
$case->detach_bug($bugids);
$case->detach_bug($params->{bug_ids});
# Result 0 on success, otherwise an exception will be thrown
return 0;
@ -363,7 +396,7 @@ sub get_bugs {
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case->{case_id};
ThrowUserError('testopia-permission-denied', {'object' => $case}) unless $case->canview;
# Result is list of bugs for the given test case
@ -372,15 +405,21 @@ sub get_bugs {
sub add_component {
my $self = shift;
my ($case_ids, $component_ids) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_ids} = shift;
$params->{components} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($case_ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($params->{case_ids});
my @results;
foreach my $id (@ids){
my $case = new Bugzilla::Extension::Testopia::TestCase($id);
unless ($case){
unless ($case->{case_id}){
push @results, {ERROR => "TestCase $id does not exist"};
next;
}
@ -389,7 +428,7 @@ sub add_component {
next;
}
eval {
$case->add_component($component_ids);
$case->add_component($params->{components});
};
if ($@){
push @results, {ERROR => $@};
@ -401,15 +440,21 @@ sub add_component {
sub remove_component {
my $self = shift;
my ($case_ids, $component_id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_ids} = shift;
$params->{component_id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($case_ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($params->{case_ids});
my @results;
foreach my $id (@ids){
my $case = new Bugzilla::Extension::Testopia::TestCase($id);
unless ($case){
unless ($case->{case_id}){
push @results, {ERROR => "TestCase $id does not exist"};
next;
}
@ -418,7 +463,7 @@ sub remove_component {
next;
}
eval {
$case->remove_component($component_id);
$case->remove_component($params->{component_id});
};
if ($@){
push @results, {ERROR => $@};
@ -436,7 +481,7 @@ sub get_components {
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case->{case_id};
ThrowUserError('testopia-permission-denied', {'object' => $case}) unless $case->canview;
# Result list of components otherwise an exception will be thrown
@ -445,15 +490,21 @@ sub get_components {
sub add_tag {
my $self = shift;
my ($case_ids, $tags) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_ids} = shift;
$params->{tags} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($case_ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($params->{case_ids});
my @results;
foreach my $id (@ids){
my $case = new Bugzilla::Extension::Testopia::TestCase($id);
unless ($case){
unless ($case->{case_id}){
push @results, {ERROR => "TestCase $id does not exist"};
next;
}
@ -462,7 +513,7 @@ sub add_tag {
next;
}
eval {
$case->add_tag($tags);
$case->add_tag($params->{tags});
};
if ($@){
push @results, {ERROR => $@};
@ -474,15 +525,21 @@ sub add_tag {
sub remove_tag {
my $self = shift;
my ($case_ids, $tag_name) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_ids} = shift;
$params->{tag} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($case_ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($params->{case_ids});
my @results;
foreach my $id (@ids){
my $case = new Bugzilla::Extension::Testopia::TestCase($id);
unless ($case){
unless ($case->{case_id}){
push @results, {ERROR => "TestCase $id does not exist"};
next;
}
@ -491,7 +548,7 @@ sub remove_tag {
next;
}
eval {
$case->remove_tag($tag_name);
$case->remove_tag($params->{tag});
};
if ($@){
push @results, {ERROR => $@};
@ -509,7 +566,7 @@ sub get_tags {
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case->{case_id};
ThrowUserError('testopia-permission-denied', {'object' => $case}) unless $case->canview;
my @results;
@ -522,20 +579,29 @@ sub get_tags {
sub link_plan {
my $self = shift;
my ($case_ids, $plan_ids) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_ids} = shift;
$params->{plan_ids} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @plans;
if (ref $plan_ids eq 'ARRAY'){
$plan_ids = join(',', @$plan_ids);
if (ref $params->{plan_ids} eq 'ARRAY'){
$params->{plan_ids} = join(',', @{$params->{plan_ids}});
}
foreach my $id (split(',', $plan_ids)){
foreach my $id (split(',', $params->{plan_ids})){
my $plan = Bugzilla::Extension::Testopia::TestPlan->new($id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $id}) unless $plan->{plan_id};
ThrowUserError("testopia-read-only", {'object' => $plan}) unless $plan->canedit;
push @plans, $plan;
}
ThrowUserError('missing-plans-list') unless scalar @plans;
my @ids = Bugzilla::Extension::Testopia::Util::process_list($case_ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($params->{case_ids});
my @results;
foreach my $id (@ids){
my $case = new Bugzilla::Extension::Testopia::TestCase($id);
@ -555,16 +621,22 @@ sub link_plan {
sub unlink_plan {
my $self = shift;
my ($case_id, $plan_id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_id} = shift;
$params->{plan_id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
my $case = new Bugzilla::Extension::Testopia::TestCase($params->{case_id});
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError("testopia-read-only", {'object' => 'case'}) unless ($case->can_unlink_plan($plan_id));
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $params->{case_id}}) unless $case->{case_id};
ThrowUserError("testopia-read-only", {'object' => 'case'}) unless ($case->can_unlink_plan($params->{plan_id}));
$case->unlink_plan($plan_id);
$case->unlink_plan($params->{plan_id});
# Result is list of plans for test case on success, otherwise an exception will be thrown
return $case->plans;
@ -572,15 +644,21 @@ sub unlink_plan {
sub add_to_run {
my $self = shift;
my ($case_ids, $run_ids) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_ids} = shift;
$params->{run_ids} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($case_ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($params->{case_ids});
my @results;
foreach my $id (@ids){
my $case = new Bugzilla::Extension::Testopia::TestCase($id);
unless ($case){
unless ($case->{case_id}){
push @results, {ERROR => "TestCase $id does not exist"};
next;
}
@ -593,7 +671,7 @@ sub add_to_run {
next;
}
eval {
$case->add_to_run($run_ids);
$case->add_to_run($params->{run_ids});
};
if ($@){
push @results, {ERROR => $@};
@ -611,7 +689,7 @@ sub get_case_run_history {
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case->{case_id};
ThrowUserError('testopia-permission-denied', {'object' => $case}) unless $case->canview;
# Result list of caseruns otherwise an exception will be thrown
@ -626,7 +704,7 @@ sub get_change_history {
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case->{case_id};
ThrowUserError('testopia-permission-denied', {'object' => $case}) unless $case->canview;
# Result list of changes otherwise an exception will be thrown
@ -641,56 +719,68 @@ sub calculate_average_time {
my $case = new Bugzilla::Extension::Testopia::TestCase($case_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case', id => $case_id}) unless $case->{case_id};
ThrowUserError('testopia-permission-denied', {'object' => $case}) unless $case->canview;
return $case->calculate_average_time;
}
sub lookup_category_id_by_name {
return { ERROR => 'This method is considered harmful and has been deprecated. Please use Bugzilla::Extension::Testopia::Product::check_catagory instead'};
}
sub lookup_category_name_by_id {
return { ERROR => 'This method has been deprecated. Please use Bugzilla::Extension::Testopia::Product::get_category instead'};
}
sub lookup_priority_id_by_name {
my $self = shift;
my ($name) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{name} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
# Result is test case priority id for the given test case priority name
return lookup_priority_by_value($name);
return lookup_priority_by_value($params->{name});
}
sub lookup_priority_name_by_id {
my $self = shift;
my ($id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
return lookup_priority($id);
return lookup_priority($params->{id});
}
sub lookup_status_id_by_name {
my $self = shift;
my ($name) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{name} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
# Result is test case status id for the given test case status name
return lookup_status_by_name($name);
return lookup_status_by_name($params->{name});
}
sub lookup_status_name_by_id {
my $self = shift;
my ($id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
return lookup_status($id);
return lookup_status($params->{id});
}
1;
@ -713,14 +803,14 @@ Provides methods for automated scripts to manipulate Testopia TestCases
=over
=item C<add_component($case_ids, $component_ids)>
=item C<add_component>
Description: Adds one or more components to the selected test cases.
Params: $case_ids - Integer/Array/String: An integer or alias representing the ID in the database,
an arry of case_ids or aliases, or a string of comma separated case_ids.
$component_ids - Integer/Array/String - The component ID, an array of Component IDs or
$components - Integer/Array/String - The component ID, an array of Component IDs or
component hashes (components can be an array of IDs, a comma separated string of IDs,
an array of Hashes, or a single hash where the
component hash = {component => 'string', product => 'string'},
@ -729,7 +819,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Array: empty on success or an array of hashes with failure
codes if a failure occured.
=item C<add_tag($case_ids, $tags)>
=item C<add_tag>
Description: Add one or more tags to the selected test cases.
@ -742,7 +832,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Array: empty on success or an array of hashes with failure
codes if a failure occured.
=item C<add_to_run($case_ids, $run_ids)>
=item C<add_to_run>
Description: Add one or more cases to the selected test runs.
@ -755,7 +845,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Array: empty on success or an array of hashes with failure
codes if a failure occured.
=item C<attach_bug($case_ids, $bug_ids)>
=item C<attach_bug>
Description: Add one or more bugs to the selected test cases.
@ -768,15 +858,15 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Array: empty on success or an array of hashes with failure
codes if a failure occured.
=item C<calculate_average_time($case_id)>
=item C<calculate_average_time>
Description: Returns an average time for completion accross all runs.
Params: $case_id - Integer/String: An integer or alias representing the ID in the database.
Params: $id - Integer/String: An integer or alias representing the ID in the database.
Returns: String: Time in "HH:MM:SS" format.
=item C<create($values)>
=item C<create>
Description: Creates a new Test Case object and stores it in the database.
@ -817,7 +907,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
an array of objects if more than one was created. If any single case threw an
error during creation, a hash with an ERROR key will be set in its place.
=item C<detach_bug($case_id, $bug_id)>
=item C<detach_bug>
Description: Remove a bug from a test case.
@ -828,7 +918,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: 0 on success.
=item C<get($case_id)>
=item C<get>
Description: Used to load an existing test case from the database.
@ -837,62 +927,62 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: A blessed Bugzilla::Extension::Testopia::TestCase object hash
=item C<get_bugs($case_id)>
=item C<get_bugs>
Description: Get the list of bugs that are associated with this test case.
Params: $case_id - Integer/String: An integer representing the ID in the database
Params: $id - Integer/String: An integer representing the ID in the database
or a string representing the unique alias for this case.
Returns: Array: An array of bug object hashes.
=item C<get_case_run_history($case_id)>
=item C<get_case_run_history>
Description: Get the list of case-runs for all runs this case appears in.
To limit this list by build or other attribute, see TestCaseRun::list.
Params: $case_id - Integer/String: An integer representing the ID in the database
Params: $id - Integer/String: An integer representing the ID in the database
or a string representing the unique alias for this case.
Returns: Array: An array of case-run object hashes.
=item C<get_change_history($case_id)>
=item C<get_change_history>
Description: Get the list of changes to the fields of this case.
Params: $case_id - Integer/String: An integer representing the ID in the database
Params: $id - Integer/String: An integer representing the ID in the database
or a string representing the unique alias for this case.
Returns: Array: An array of hashes with changed fields and their details.
=item C<get_components($case_id)>
=item C<get_components>
Description: Get the list of components attached to this case.
Params: $case_id - Integer/String: An integer representing the ID in the database
Params: $id - Integer/String: An integer representing the ID in the database
or a string representing the unique alias for this case.
Returns: Array: An array of component object hashes.
=item C<get_plans($case_id)>
=item C<get_plans>
Description: Get the list of plans that this case is linked to.
Params: $case_id - Integer/String: An integer representing the ID in the database
Params: $id - Integer/String: An integer representing the ID in the database
or a string representing the unique alias for this case.
Returns: Array: An array of test plan object hashes.
=item C<get_tags($case_id)>
=item C<get_tags>
Description: Get the list of tags attached to this case.
Params: $case_id - Integer/String: An integer representing the ID in the database
Params: $id - Integer/String: An integer representing the ID in the database
or a string representing the unique alias for this case.
Returns: Array: An array of tag object hashes.
=item C<get_text($case_id, $version)>
=item C<get_text>
Description: The associated large text fields: Action, Expected Results, Setup, Breakdown
for a given version.
@ -905,7 +995,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Hash: Text fields and values.
=item C<link_plan($case_ids, $plan_id)>
=item C<link_plan>
Description: Link test cases to the given plan.
@ -917,7 +1007,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Array: Array of failure codes or an empty array.
=item C<list($query)>
=item C<list>
Description: Performs a search and returns the resulting list of test cases.
@ -1018,7 +1108,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Array: Matching test cases are retuned in a list of hashes.
=item C<list_count($query)>
=item C<list_count>
Description: Performs a search and returns the resulting count of cases.
@ -1026,10 +1116,6 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Integer - total matching cases.
=item C<lookup_category_name_by_id> B<DEPRECATED - CONSIDERED HARMFUL> Use Bugzilla::Extension::Testopia::Product::get_category instead
=item C<lookup_category_id_by_name> B<DEPRECATED - CONSIDERED HARMFUL> Use Bugzilla::Extension::Testopia::Product::check_category instead
=item C<lookup_priority_name_by_id>
Params: $id - Integer: ID of the case status to return
@ -1048,13 +1134,13 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: String: the status name.
=item C<lookup_status_id_by_name>
=item C<lookup_status_id_by_name>
Params: $name - String: the status name.
Returns: Integer: ID of the case status.
=item C<remove_component($case_id, $component_id)>
=item C<remove_component>
Description: Removes selected component from the selected test case.
@ -1065,7 +1151,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Array: Empty on success.
=item C<remove_tag($case_id, $tag)>
=item C<remove_tag>
Description: Remove a tag from a case.
@ -1076,7 +1162,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Array: Empty on success.
=item C<store_text($case_id, $action, $effect, $setup, $breakdown, [$author_id])>
=item C<store_text>
Description: Update the large text fields of a case.
@ -1087,18 +1173,18 @@ Provides methods for automated scripts to manipulate Testopia TestCases
Returns: Integer: Version of the stored text
=item C<unlink_plan($case_id, $plan_id)>
=item C<unlink_plan>
Description: Unlink a test case from the given plan. If only one plan is linked, this will delete
the test case.
Params: $case_ids - Integer/String: An integer or alias representing the ID in the database.
Params: $case_id - Integer/String: An integer or alias representing the ID in the database.
$plan_id - Integer: An integer representing the ID in the database.
Returns: Array: Array of plans still linked if any, empty if not.
=item C<update($ids, $values)>
=item C<update>
Description: Updates the fields of the selected case or cases.
@ -1118,6 +1204,7 @@ Provides methods for automated scripts to manipulate Testopia TestCases
+-------------------+----------------+
| Field | Type |
+-------------------+----------------+
| ids (redonly) | Integer/String |
| status | Integer/String |
| category | Integer/String |
| priority | Integer/String |

View File

@ -39,26 +39,40 @@ use Bugzilla::Extension::Testopia::Util;
sub get {
my $self = shift;
my ($run_id, $case_id, $build_id, $env_id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{run_id} = shift;
$params->{case_id} = shift;
$params->{build_id} = shift;
$params->{env_id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
if ($build_id && $build_id !~ /^\d+$/){
my $run = Bugzilla::Extension::Testopia::TestRun->new($run_id);
if ($params->{build_id} && $params->{build_id} !~ /^\d+$/){
my $run = Bugzilla::Extension::Testopia::TestRun->new($params->{run_id});
ThrowUserError('invalid-test-id-non-existent') unless $run;
my $build = Bugzilla::Extension::Testopia::Build::check_build($build_id, $run->product, "THROW");
$build_id = $build->id;
my $build = Bugzilla::Extension::Testopia::Build::check_build($params->{build_id}, $run->product, "THROW");
$params->{build_id} = $build->id;
}
if ($env_id && $env_id !~ /^\d+$/){
my $run = Bugzilla::Extension::Testopia::TestRun->new($run_id);
if ($params->{env_id} && $params->{env_id} !~ /^\d+$/){
my $run = Bugzilla::Extension::Testopia::TestRun->new($params->{run_id});
ThrowUserError('invalid-test-id-non-existent') unless $run;
my $environment = Bugzilla::Extension::Testopia::Build::check_environment($env_id, $run->product, "THROW");
$env_id = $environment->id;
my $environment = Bugzilla::Extension::Testopia::Build::check_environment($params->{env_id}, $run->product, "THROW");
$params->{env_id} = $environment->id;
}
#Result is a test case run hash map
my $caserun = new Bugzilla::Extension::Testopia::TestCaseRun($run_id, $case_id, $build_id, $env_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $run_id}) unless $caserun;
my $caserun;
if ($params->{id}){
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{id});
}
else {
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{run_id}, $params->{case_id}, $params->{build_id}, $params->{env_id});
}
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $params->{run_id}}) unless $caserun->{case_run_id};
ThrowUserError('testopia-permission-denied', {'object' => $caserun}) unless $caserun->canview;
return $caserun;
@ -143,13 +157,56 @@ sub create {
sub update {
my $self = shift;
my ($run_id, $case_id, $build_id, $env_id, $new_values) = @_;
my ($new_values) = @_;
if (ref $new_values ne 'HASH'){
$new_values = {};
if (ref $_[4] eq 'HASH'){
$new_values = $_[4];
}
else {
$new_values = $_[1];
}
$new_values->{run_id} = $_[0];
$new_values->{case_id} = $_[1];
$new_values->{build_id} = $_[2];
$new_values->{env_id} = $_[3];
}
$new_values->{'case_run_status_id'} ||= $new_values->{'status'};
$new_values->{'build_id'} ||= $new_values->{'build'};
$new_values->{'environment_id'} ||= $new_values->{'environment'};
$new_values->{'priority_id'} ||= $new_values->{'priority'};
my $run_id = $new_values->{run_id};
my $case_id = $new_values->{case_id};
my $build_id = $new_values->{build_id};
my $env_id = $new_values->{env_id};
Bugzilla->login(LOGIN_REQUIRED);
my @caseruns;
my @ids = Bugzilla::Extension::Testopia::Util::process_list($run_id);
if (ref $case_id eq 'HASH' && !$build_id){
my @ids;
if ($new_values->{ids}){
@ids = Bugzilla::Extension::Testopia::Util::process_list($new_values->{ids});
}
else {
@ids = Bugzilla::Extension::Testopia::Util::process_list($run_id);
}
if ($new_values->{ids}){
foreach my $id (@ids){
my $caserun = new Bugzilla::Extension::Testopia::TestCaseRun($id);
if ($caserun){
push @caseruns, $caserun;
}
else {
push @caseruns, {ERROR => 'Case-run does not exist'};
}
}
}
elsif ((ref $case_id eq 'HASH' && !$build_id)){
$new_values = $case_id;
foreach my $id (@ids){
my $caserun = new Bugzilla::Extension::Testopia::TestCaseRun($id);
@ -164,7 +221,7 @@ sub update {
else {
foreach my $id (@ids){
my $caserun = new Bugzilla::Extension::Testopia::TestCaseRun($run_id,$case_id,$build_id,$env_id);
if ($caserun){
if ($caserun->{case_run_id}){
push @caseruns, $caserun;
}
else {
@ -173,11 +230,6 @@ sub update {
}
}
$new_values->{'case_run_status_id'} ||= $new_values->{'status'};
$new_values->{'build_id'} ||= $new_values->{'build'};
$new_values->{'environment_id'} ||= $new_values->{'environment'};
$new_values->{'priority_id'} ||= $new_values->{'priority'};
my @results;
foreach my $caserun (@caseruns){
@ -189,6 +241,24 @@ sub update {
push @results, {ERROR => "You do not have rights to edit this test case"};
next;
}
if ($new_values->{'build_id'} && trim($new_values->{'build_id'}) !~ /^\d+$/ ){
my $build = Bugzilla::Extension::Testopia::Build::check_build($new_values->{'build_id'}, $caserun->run->plan->product);
if (!$build){
push @results, {ERROR => "Invalid build for product"};
next;
}
$build = Bugzilla::Extension::Testopia::Build->new($build);
$new_values->{'build_id'} = $build->id;
}
if ($new_values->{'environment_id'} && trim($new_values->{'environment_id'}) !~ /^\d+$/ ){
my $environment = Bugzilla::Extension::Testopia::Environment::check_environment($new_values->{'environment_id'}, $caserun->run->plan->product);
if (!$environment){
push @results, {ERROR => "Invalid environment for product"};
next;
}
$environment = Bugzilla::Extension::Testopia::Environment->new($environment);
$new_values->{'environment_id'} = $environment->id;
}
$run_id = $caserun->run_id;
$case_id = $caserun->case_id;
@ -246,34 +316,57 @@ sub update {
sub lookup_status_id_by_name {
my $self = shift;
my ($name) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{name} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
# Result is test case run status id for the given test case run status name
return Bugzilla::Extension::Testopia::TestCaseRun::lookup_status_by_name($name);
return Bugzilla::Extension::Testopia::TestCaseRun::lookup_status_by_name($params->{name});
}
sub lookup_status_name_by_id {
my $self = shift;
my ($id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
# Result is test case run status name for the given test case run status id
return Bugzilla::Extension::Testopia::TestCaseRun::lookup_status($id);
return Bugzilla::Extension::Testopia::TestCaseRun::lookup_status($params->{id});
}
sub get_history {
my $self = shift;
my ($run_id, $case_id, $build_id, $env_id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{run_id} = shift;
$params->{case_id} = shift;
$params->{build_id} = shift;
$params->{env_id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
#Result is a test case run hash map
my $caserun = new Bugzilla::Extension::Testopia::TestCaseRun($run_id, $case_id, $build_id, $env_id);
my $caserun;
if ($params->{id}){
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{id});
}
else {
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{run_id}, $params->{case_id}, $params->{build_id}, $params->{env_id});
}
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $run_id}) unless $caserun;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $params->{run_id}}) unless $caserun->{case_run_id};
ThrowUserError('testopia-permission-denied', {'object' => $caserun}) unless $caserun->canview;
return $caserun->get_case_run_list;
@ -282,40 +375,68 @@ sub get_history {
sub attach_bug {
my $self = shift;
my ($run_id, $case_id, $build_id, $env_id, $bug_ids) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{run_id} = shift;
$params->{case_id} = shift;
$params->{build_id} = shift;
$params->{env_id} = shift;
$params->{bug_ids} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
#Result is a test case run hash map
my $caserun = new Bugzilla::Extension::Testopia::TestCaseRun($run_id, $case_id, $build_id, $env_id);
# If we have just the id, the third arg will not be set.
$bug_ids = $case_id unless $build_id;
my $caserun;
if ($params->{id}){
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{id});
}
else {
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{run_id}, $params->{case_id}, $params->{build_id}, $params->{env_id});
}
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $run_id}) unless $caserun;
# If we have just the id, the third arg will not be set.
$params->{bug_ids} = $params->{case_id} unless $params->{build_id};
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $params->{run_id}}) unless $caserun->{case_run_id};
ThrowUserError('testopia-read-only', {'object' => $caserun}) unless $caserun->canedit;
$caserun->attach_bug($bug_ids);
$caserun->attach_bug($params->{bug_ids});
return undef;
}
sub detach_bug {
my $self = shift;
my ($run_id, $case_id, $build_id, $env_id, $bug_id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{run_id} = shift;
$params->{case_id} = shift;
$params->{build_id} = shift;
$params->{env_id} = shift;
$params->{bug_id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
#Result is a test case run hash map
my $caserun = new Bugzilla::Extension::Testopia::TestCaseRun($run_id, $case_id, $build_id, $env_id);
my $caserun;
if ($params->{id}){
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{id});
}
else {
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{run_id}, $params->{case_id}, $params->{build_id}, $params->{env_id});
}
# If we have just the id, the third arg will not be set.
$bug_id = $case_id unless $build_id;
$params->{bug_id} = $params->{case_id} unless $params->{build_id};
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $run_id}) unless $caserun;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $params->{run_id}}) unless $caserun->{case_run_id};
ThrowUserError('testopia-read-only', {'object' => $caserun}) unless $caserun->canedit;
$caserun->detach_bug($bug_id);
$caserun->detach_bug($params->{bug_id});
# Result undef on success, otherwise an exception will be thrown
return undef;
@ -323,14 +444,27 @@ sub detach_bug {
sub get_bugs {
my $self = shift;
my ($run_id, $case_id, $build_id, $env_id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{run_id} = shift;
$params->{case_id} = shift;
$params->{build_id} = shift;
$params->{env_id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
#Result is a test case run hash map
my $caserun = new Bugzilla::Extension::Testopia::TestCaseRun($run_id, $case_id, $build_id, $env_id);
my $caserun;
if ($params->{id}){
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{id});
}
else {
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{run_id}, $params->{case_id}, $params->{build_id}, $params->{env_id});
}
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $run_id}) unless $caserun;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $params->{run_id}}) unless $caserun->{case_run_id};
ThrowUserError('testopia-permission-denied', {'object' => $caserun}) unless $caserun->canview;
return $caserun->bugs;
@ -338,14 +472,27 @@ sub get_bugs {
sub get_completion_time {
my $self = shift;
my ($run_id, $case_id, $build_id, $env_id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{run_id} = shift;
$params->{case_id} = shift;
$params->{build_id} = shift;
$params->{env_id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
#Result is a test case run hash map
my $caserun = new Bugzilla::Extension::Testopia::TestCaseRun($run_id, $case_id, $build_id, $env_id);
my $caserun;
if ($params->{id}){
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{id});
}
else {
$caserun = new Bugzilla::Extension::Testopia::TestCaseRun($params->{run_id}, $params->{case_id}, $params->{build_id}, $params->{env_id});
}
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $run_id}) unless $caserun;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Case Run', id => $params->{run_id}}) unless $caserun->{case_run_id};
ThrowUserError('testopia-permission-denied', {'object' => $caserun}) unless $caserun->canview;
return $caserun->completion_time;
@ -388,32 +535,32 @@ TestCaseRun->get($run_id, $case_id, $build_id, $environment_id)
=over
=item C<attach_bug($caserun_id, $bug_ids)>
=item C<attach_bug>
Description: Add one or more bugs to the selected test case-runs.
Params: $case_run_id - Integer: An integer representing the ID in the database.
Params: $id - Integer: An integer representing the ID in the database.
$bug_ids - Integer/Array/String: An integer or alias representing the ID in the database,
an array of bug_ids or aliases, or a string of comma separated bug_ids.
Returns: undef.
=item C<attach_bug($run_id, $case_id, $build_id, $environment_id, $bug_ids)>
=item C<attach_bug>
Description: Add one or more bugs to the selected test case-runs.
Params: $case_id - Integer: An integer representing the ID of the test case in the database.
$run_id - Integer: An integer representing the ID of the test run in the database.
Params: $run_id - Integer: An integer representing the ID of the test run in the database.
$case_id - Integer: An integer representing the ID of the test case in the database.
$build_id - Integer: An integer representing the ID of the test build in the database.
$environment_id - Integer: An integer representing the ID of the environment in the database.
$env_id - Integer: An integer representing the ID of the environment in the database.
$bug_ids - Integer/Array/String: An integer or alias representing the ID in the database,
an array of bug_ids or aliases, or a string of comma separated bug_ids.
Returns: undef.
=item C<create($values)>
=item C<create>
Description: Creates a new Test Case Run object and stores it in the database.
@ -437,114 +584,114 @@ TestCaseRun->get($run_id, $case_id, $build_id, $environment_id)
Returns: The newly created object hash.
=item C<detach_bug($caserun_id, $bug_id)>
=item C<detach_bug>
Description: Remove a bug from a test case-run.
Params: $caserun_id - Integer: An integer representing the ID in the database.
Params: $id - Integer: An integer representing the ID in the database.
$bug_ids - Integer/Array/String: An integer or alias representing the ID in the database,
an array of bug_ids or aliases, or a string of comma separated bug_ids.
Returns: undef.
=item C<detach_bug($run_id, $case_id, $build_id, $environment_id, $bug_id)>
=item C<detach_bug>
Description: Remove a bug from a test case-run.
Params: $case_id - Integer: An integer representing the ID of the test case in the database.
$run_id - Integer: An integer representing the ID of the test run in the database.
Params: $run_id - Integer: An integer representing the ID of the test run in the database.
$case_id - Integer: An integer representing the ID of the test case in the database.
$build_id - Integer: An integer representing the ID of the test build in the database.
$environment_id - Integer: An integer representing the ID of the environment in the database.
$env_id - Integer: An integer representing the ID of the environment in the database.
$bug_id - Integer: An integer or alias representing the ID of
the bug in the database,
Returns: undef.
=item C<get($caserun_id)>
=item C<get>
Description: Used to load an existing test case-run from the database.
Params: $caserun_id - Integer: An integer representing the ID in
Params: $id - Integer: An integer representing the ID in
the database for this case-run.
Returns: A blessed Bugzilla::Extension::Testopia::TestCaseRun object hash
=item C<get($run_id, $case_id, $build_id, $environment_id)>
=item C<get>
Description: Used to load an existing test case from the database.
Params: $case_id - Integer: An integer representing the ID of the test case in the database.
$run_id - Integer: An integer representing the ID of the test run in the database.
Params: $run_id - Integer: An integer representing the ID of the test run in the database.
$case_id - Integer: An integer representing the ID of the test case in the database.
$build_id - Integer: An integer representing the ID of the test build in the database.
$environment_id - Integer: An integer representing the ID of the environment in the database.
$env_id - Integer: An integer representing the ID of the environment in the database.
Returns: A blessed Bugzilla::Extension::Testopia::TestCaseRun object hash
=item C<get_bugs($caserun_id)>
=item C<get_bugs>
Description: Get the list of bugs that are associated with this test case.
Params: $caserun_id - Integer: An integer representing the ID in
Params: $id - Integer: An integer representing the ID in
the database for this case-run.
Returns: Array: An array of bug object hashes.
=item C<get_bugs($run_id, $case_id, $build_id, $environment_id)>
=item C<get_bugs>
Description: Get the list of bugs that are associated with this test case.
Params: $case_id - Integer: An integer representing the ID of the test case in the database.
$run_id - Integer: An integer representing the ID of the test run in the database.
Params: $run_id - Integer: An integer representing the ID of the test run in the database.
$case_id - Integer: An integer representing the ID of the test case in the database.
$build_id - Integer: An integer representing the ID of the test build in the database.
$environment_id - Integer: An integer representing the ID of the environment in the database.
$env_id - Integer: An integer representing the ID of the environment in the database.
Returns: Array: An array of bug object hashes.
=item C<get_completion_time($caserun_id)>
=item C<get_completion_time>
Description: Returns the time in seconds that it took for this case to complete.
Params: $caserun_id - Integer: An integer representing the ID in
Params: $id - Integer: An integer representing the ID in
the database for this case-run.
Returns: Integer: Seconds since run was started till this case was completed.
=item C<get_completion_time($run_id, $case_id, $build_id, $environment_id)>
=item C<get_completion_time>
Description: Returns the time in seconds that it took for this case to complete.
Params: $case_id - Integer: An integer representing the ID of the test case in the database.
$run_id - Integer: An integer representing the ID of the test run in the database.
Params: $run_id - Integer: An integer representing the ID of the test run in the database.
$case_id - Integer: An integer representing the ID of the test case in the database.
$build_id - Integer: An integer representing the ID of the test build in the database.
$environment_id - Integer: An integer representing the ID of the environment in the database.
$env_id - Integer: An integer representing the ID of the environment in the database.
Returns: Integer: Seconds since run was started till this case was completed.
=item C<get_history($caserun_id)>
=item C<get_history>
Description: Get the list of case-runs for all runs this case appears in.
To limit this list by build or other attribute, see TestCaseRun::list.
Params: $caserun_id - Integer: An integer representing the ID in
Params: $id - Integer: An integer representing the ID in
the database for this case-run.
Returns: Array: An array of case-run object hashes.
=item C<get_history($run_id, $case_id, $build_id, $environment_id)>
=item C<get_history>
Description: Get the list of case-runs for all runs this case appears in.
To limit this list by build or other attribute, see TestCaseRun::list.
Params: $case_id - Integer: An integer representing the ID of the test case in the database.
$run_id - Integer: An integer representing the ID of the test run in the database.
Params: $run_id - Integer: An integer representing the ID of the test run in the database.
$case_id - Integer: An integer representing the ID of the test case in the database.
$build_id - Integer: An integer representing the ID of the test build in the database.
$environment_id - Integer: An integer representing the ID of the environment in the database.
$env_id - Integer: An integer representing the ID of the environment in the database.
Returns: Array: An array of case-run object hashes.
=item C<list($query)>
=item C<list>
Description: Performs a search and returns the resulting list of test cases.
@ -649,7 +796,7 @@ TestCaseRun->get($run_id, $case_id, $build_id, $environment_id)
Returns: Array: Matching test cases are retuned in a list of hashes.
=item C<list_count($query)>
=item C<list_count>
Description: Performs a search and returns the resulting count of cases.
@ -657,23 +804,23 @@ TestCaseRun->get($run_id, $case_id, $build_id, $environment_id)
Returns: Integer - total matching cases.
=item C<lookup_status_name_by_id>
=item lookup_status_name_by_id
Params: $id - Integer: ID of the status to return
Returns: String: the status name.
=item C<lookup_status_id_by_name>
=item lookup_status_id_by_name
Params: $name - String: the status name.
Returns: Integer: ID of the status.
=item C<update($caserun_ids, $values)>
=item C<update>
Description: Updates the fields of the selected case-runs.
Params: $caserun_ids - Integer/String/Array
Params: $ids - Integer/String/Array
Integer: A single TestCaseRun ID.
String: A comma separates string of TestCaseRun IDs for batch
processing.
@ -699,14 +846,14 @@ TestCaseRun->get($run_id, $case_id, $build_id, $environment_id)
update on any particular object failed, the hash will contain a
ERROR key and the message as to why it failed.
=item C<update($run_id, $case_id, $build_id, $environment_id, $values)>
=item C<update>
Description: Updates the fields of the selected case-run.
Params: $case_id - Integer: An integer representing the ID of the test case in the database.
$run_id - Integer: An integer representing the ID of the test run in the database.
Params: $run_id - Integer: An integer representing the ID of the test run in the database.
$case_id - Integer: An integer representing the ID of the test case in the database.
$build_id - Integer: An integer representing the ID of the test build in the database.
$environment_id - Integer: An integer representing the ID of the environment in the database.
$env_id - Integer: An integer representing the ID of the environment in the database.
$values - Hash of keys matching TestCaseRun fields and the new values
to set each field to. See above.

View File

@ -44,7 +44,7 @@ sub get {
# Result is a plan object hash
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Plan', id => $plan_id}) unless $plan->{plan_id};
ThrowUserError('testopia-permission-denied', {'object' => $plan}) unless $plan->canview;
$plan->test_run_count();
@ -113,13 +113,18 @@ sub create {
sub update {
my $self =shift;
my ($plan_id, $new_values) = @_;
my ($new_values) = @_;
if(ref $new_values ne 'HASH'){
$new_values = $_[1];
$new_values->{id} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
my $plan = new Bugzilla::Extension::Testopia::TestPlan($new_values->{id});
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $new_values->{id}}) unless $plan->{plan_id};
ThrowUserError('testopia-read-only', {'object' => $plan}) unless $plan->canedit;
$new_values->{'type_id'} ||= $new_values->{'type'};
@ -127,7 +132,7 @@ sub update {
$plan->set_name(trim($new_values->{'name'}));
$plan->set_default_product_version($new_values->{'default_product_version'});
$plan->set_type($new_values->{'type_id'});
$plan->set_isactive($new_values->{'isactive'});
$plan->set_isactive($new_values->{'isactive'}) if defined $new_values->{'isactive'};
$plan->update();
@ -137,36 +142,49 @@ sub update {
sub get_text {
my $self = shift;
my ($plan_id, $version) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{plan_id} = shift;
$params->{version} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
my $plan = new Bugzilla::Extension::Testopia::TestPlan($params->{plan_id});
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $params->{plan_id}}) unless $plan->{plan_id};
ThrowUserError('testopia-permission-denied', {'object' => $plan}) unless $plan->canview;
#Result is the latest test plan doc hash map
return $plan->text($version);
return $plan->text($params->{version});
}
sub store_text {
my $self = shift;
my ($plan_id, $text, $author_id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{plan_id} = shift;
$params->{text} = shift;
$params->{author_id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
my $plan = new Bugzilla::Extension::Testopia::TestPlan($params->{plan_id});
$author_id ||= Bugzilla->user->id;
if ($author_id !~ /^\d+$/){
$author_id = Bugzilla::User::login_to_id($author_id, "THROWERROR");
$params->{author_id} ||= Bugzilla->user->id;
if ($params->{author_id} !~ /^\d+$/){
$params->{author_id} = Bugzilla::User::login_to_id($params->{author_id}, "THROWERROR");
}
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $params->{plan_id}}) unless $plan->{plan_id};
ThrowUserError('testopia-read-only', {'object' => $plan}) unless $plan->canedit;
my $version = $plan->store_text($plan_id, $author_id, $text);
my $version = $plan->store_text($params->{plan_id}, $params->{author_id}, $params->{text});
# Result is new test plan doc version on success, otherwise an exception will be thrown
return $version;
@ -181,7 +199,7 @@ sub get_test_cases {
# Result is a plan object hash
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $plan_id}) unless $plan->{plan_id};
ThrowUserError('testopia-permission-denied', {'object' => $plan}) unless $plan->canview;
# Result is list of test cases for the given test plan
@ -197,7 +215,7 @@ sub get_case_tags {
# Result is a plan object hash
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $plan_id}) unless $plan->{plan_id};
ThrowUserError('testopia-permission-denied', {'object' => $plan}) unless $plan->canview;
# Result is list of test cases for the given test plan
@ -213,7 +231,7 @@ sub get_test_runs {
# Result is a plan object hash
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Plan', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Plan', id => $plan_id}) unless $plan->{plan_id};
ThrowUserError('testopia-permission-denied', {'object' => $plan}) unless $plan->canview;
# Result is list of test runs for the given test plan
@ -228,7 +246,7 @@ sub get_change_history {
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $plan_id}) unless $plan->{plan_id};
ThrowUserError('testopia-permission-denied', {'object' => $plan}) unless $plan->canview;
# Result list of changes otherwise an exception will be thrown
@ -244,7 +262,7 @@ sub get_product {
# Result is a plan object hash
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Product', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Product', id => $plan_id}) unless $plan->{plan_id};
ThrowUserError('testopia-permission-denied', {'object' => $plan}) unless $plan->canview;
# Result is list of test cases for the given test plan
@ -253,35 +271,51 @@ sub get_product {
sub lookup_type_name_by_id {
my $self =shift;
my ($id) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{id} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
# Result is test plan type name for the given test plan type id
return lookup_type($id);
return lookup_type($params->{id});
}
sub lookup_type_id_by_name {
my $self =shift;
my ($name) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{name} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
# Result is test plan type id for the given test plan type name
return Bugzilla::Extension::Testopia::TestPlan::lookup_type_by_name($name);
return Bugzilla::Extension::Testopia::TestPlan::lookup_type_by_name($params->{name});
}
sub add_tag {
my $self = shift;
my ($plan_ids, $tags) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{plan_ids} = shift;
$params->{tags} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($plan_ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($params->{plan_ids});
my @results;
foreach my $id (@ids){
my $plan = new Bugzilla::Extension::Testopia::TestPlan($id);
unless ($plan){
unless ($plan->{plan_id}){
push @results, {ERROR => "TestPlan $id does not exist"};
next;
}
@ -290,7 +324,7 @@ sub add_tag {
next;
}
eval {
$plan->add_tag($tags);
$plan->add_tag($params->{tags});
};
if ($@){
push @results, {ERROR => $@};
@ -302,16 +336,22 @@ sub add_tag {
sub remove_tag {
my $self = shift;
my ($plan_id, $tag_name) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{plan_id} = shift;
$params->{tag} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
my $plan = new Bugzilla::Extension::Testopia::TestPlan($params->{plan_id});
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $params->{plan_id}}) unless $plan->{plan_id};
ThrowUserError('testopia-read-only', {'object' => $plan}) unless $plan->canedit;
$plan->remove_tag($tag_name);
$plan->remove_tag($params->{tag});
# Result 0 on success, otherwise an exception will be thrown
return 0;
@ -325,7 +365,7 @@ sub get_tags {
my $plan = new Bugzilla::Extension::Testopia::TestPlan($plan_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $plan_id}) unless $plan;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Plan', id => $plan_id}) unless $plan->{plan_id};
ThrowUserError('testopia-permission-denied', {'object' => $plan}) unless $plan->canview;
my @results;
@ -356,7 +396,7 @@ Provides methods for automated scripts to manipulate Testopia TestPlans
=over
=item C<add_tag($plan_ids, $tags)>
=item C<add_tag>
Description: Add one or more tags to the selected test plans.
@ -369,7 +409,7 @@ Provides methods for automated scripts to manipulate Testopia TestPlans
Returns: Array: empty on success or an array of hashes with failure
codes if a failure occured.
=item C<create($values)>
=item C<create>
Description: Creates a new Test Plan object and stores it in the database.
@ -387,7 +427,7 @@ Provides methods for automated scripts to manipulate Testopia TestPlans
Returns: The newly created object hash.
=item C<get($plan_id)>
=item C<get>
Description: Used to load an existing test plan from the database.
@ -395,55 +435,55 @@ Provides methods for automated scripts to manipulate Testopia TestPlans
Returns: Hash: A blessed Bugzilla::Extension::Testopia::TestPlan object hash
=item C<get_change_history($plan_id)>
=item C<get_change_history>
Description: Get the list of changes to the fields of this plan.
Params: $plan_id - Integer: An integer representing the ID of this plan in the database
Params: $id - Integer: An integer representing the ID of this plan in the database
Returns: Array: An array of hashes with changed fields and their details.
=item C<get_product($plan_id)>
=item C<get_product>
Description: Get the Product the plan is assiciated with.
Params: $plan_id - Integer: An integer representing the ID of the plan in the database.
Params: $id - Integer: An integer representing the ID of the plan in the database.
Returns: Hash: A blessed Bugzilla::Extension::Testopia::Product hash.
=item C<get_tags($plan_id)>
=item C<get_tags>
Description: Get the list of tags attached to this plan.
Params: $plan_id - Integer An integer representing the ID of this plan in the database
Params: $id - Integer An integer representing the ID of this plan in the database
Returns: Array: An array of tag object hashes.
=item C<get_test_cases($plan_id)>
=item C<get_test_cases>
Description: Get the list of cases that this plan is linked to.
Params: $plan_id - Integer: An integer representing the ID of the plan in the database
Params: $id - Integer: An integer representing the ID of the plan in the database
Returns: Array: An array of test case object hashes.
=item C<get_case_tags($plan_id)>
=item C<get_case_tags>
Description: Get the list of tags associated with the cases that this plan is linked to.
Params: $plan_id - Integer: An integer representing the ID of the plan in the database
Params: $id - Integer: An integer representing the ID of the plan in the database
Returns: Array: An array of tag object hashes.
=item C<get_test_runs($plan_id)>
=item C<get_test_runs>
Description: Get the list of runs in this plan.
Params: $plan_id - Integer: An integer representing the ID of this plan in the database
Params: $id - Integer: An integer representing the ID of this plan in the database
Returns: Array: An array of test run object hashes.
=item C<get_text($plan_id, $version)>
=item C<get_text>
Description: The plan document for a given test plan.
@ -454,7 +494,7 @@ Provides methods for automated scripts to manipulate Testopia TestPlans
Returns: Hash: Text and author information.
=item C<list($query)>
=item C<list>
Description: Performs a search and returns the resulting list of test plans.
@ -537,7 +577,7 @@ Provides methods for automated scripts to manipulate Testopia TestPlans
Returns: Array: Matching test plans are retuned in a list of plan object hashes.
=item C<list_count($query)>
=item C<list_count>
Description: Performs a search and returns the resulting count of plans.
@ -545,19 +585,19 @@ Provides methods for automated scripts to manipulate Testopia TestPlans
Returns: Integer - total matching plans.
=item C<lookup_type_id_by_name>
=item lookup_type_id_by_name
Params: $name - String: the plan type.
Returns: Integer: ID of the plan type.
=item C<lookup_type_name_by_id>
=item lookup_type_name_by_id
Params: $id - Integer: ID of the plan type to return
Returns: String: the type name.
=item C<remove_tag($plan_id, $tag)>
=item C<remove_tag>
Description: Remove a tag from a plan.
@ -567,7 +607,7 @@ Provides methods for automated scripts to manipulate Testopia TestPlans
Returns: 0 on success.
=item C<store_text($plan_id, $text, [$author_id])>
=item C<store_text>
Description: Update the document field of a plan.
@ -578,17 +618,18 @@ Provides methods for automated scripts to manipulate Testopia TestPlans
Returns: Integer: The new text version
=item C<update($ids, $values)>
=item C<update>
Description: Updates the fields of the selected test plan.
Params: $ids - Integer: A single TestPlan ID.
Params: $id - Integer: A single TestPlan ID.
$values - Hash of keys matching TestPlan fields and the new values
to set each field to.
+-------------------------+----------------+
| Field | Type |
+-------------------------+----------------+
| id (readonly) | String |
| name | String |
| type | Integer/String |
| default_product_version | String |

View File

@ -47,7 +47,7 @@ sub get {
# Result is a run object hash
my $run = new Bugzilla::Extension::Testopia::TestRun($run_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $run_id}) unless $run;
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $run_id}) unless $run->{run_id};
ThrowUserError('testopia-permission-denied', {'object' => $run}) unless $run->canview;
$run->{'case_count'} = $run->case_count();
@ -131,7 +131,7 @@ sub create {
foreach my $c (@cases){
my $case = Bugzilla::Extension::Testopia::TestCase->new($c);
$run->add_case_run($case->id, $case->sortkey) if $case;
$run->add_case_run($case->id, $case->sortkey) if $case->{case_id};
}
return $run;
@ -139,15 +139,21 @@ sub create {
sub add_cases {
my $self = shift;
my ($case_ids, $run_ids) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{case_ids} = shift;
$params->{run_ids} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($case_ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($params->{case_ids});
my @results;
foreach my $id (@ids){
my $case = new Bugzilla::Extension::Testopia::TestCase($id);
unless ($case){
unless ($case->{case_id}){
push @results, {ERROR => "TestCase $id does not exist"};
next;
}
@ -156,7 +162,7 @@ sub add_cases {
next;
}
eval {
$case->add_to_run($run_ids);
$case->add_to_run($params->{run_ids});
};
if ($@){
push @results, {ERROR => $@};
@ -168,13 +174,18 @@ sub add_cases {
sub update {
my $self =shift;
my ($run_id, $new_values) = @_;
my ($new_values) = @_;
if(ref $new_values ne 'HASH'){
$new_values = $_[1];
$new_values->{id} = $_[0];
}
Bugzilla->login(LOGIN_REQUIRED);
my $run = new Bugzilla::Extension::Testopia::TestRun($run_id);
my $run = new Bugzilla::Extension::Testopia::TestRun($new_values->{id});
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Run', id => $run_id}) unless $run;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Run', id => $new_values->{id}}) unless $run->{run_id};
ThrowUserError('testopia-read-only', {'object' => $run}) unless $run->canedit;
$new_values->{'manager_id'} ||= $new_values->{'manager'};
@ -226,7 +237,7 @@ sub get_change_history {
my $run = new Bugzilla::Extension::Testopia::TestRun($run_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Run', id => $run_id}) unless $run;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Run', id => $run_id}) unless $run->{run_id};
ThrowUserError('testopia-permission-denied', {'object' => $run}) unless $run->canview;
# Result list of changes otherwise an exception will be thrown
@ -242,7 +253,7 @@ sub get_test_cases {
# Result is a run object hash
my $run = new Bugzilla::Extension::Testopia::TestRun($run_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $run_id}) unless $run;
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $run_id}) unless $run->{run_id};
ThrowUserError('testopia-permission-denied', {'object' => $run}) unless $run->canview;
# Result is list of test cases for the given test run
@ -258,7 +269,7 @@ sub get_case_tags {
# Result is a run object hash
my $run = new Bugzilla::Extension::Testopia::TestRun($run_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $run_id}) unless $run;
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $run_id}) unless $run->{run_id};
ThrowUserError('testopia-permission-denied', {'object' => $run}) unless $run->canview;
# Result is list of test cases for the given test run
@ -267,18 +278,24 @@ sub get_case_tags {
sub get_test_case_runs {
my $self = shift;
my ($run_id, $current) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{id} = shift;
$params->{current} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
# Result is a run object hash
my $run = new Bugzilla::Extension::Testopia::TestRun($run_id);
my $run = new Bugzilla::Extension::Testopia::TestRun($params->{id});
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $run_id}) unless $run;
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $params->{id} }) unless $run->{run_id};
ThrowUserError('testopia-permission-denied', {'object' => $run}) unless $run->canview;
# Result is list of test cases for the given test run
return $run->current_caseruns if $current;
return $run->current_caseruns if $params->{current};
return $run->caseruns;
}
@ -291,32 +308,30 @@ sub get_test_plan {
# Result is a run object hash
my $run = new Bugzilla::Extension::Testopia::TestRun($run_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $run_id}) unless $run;
ThrowUserError('invalid-test-id-non-existent', {type => 'Build', id => $run_id}) unless $run->{run_id};
ThrowUserError('testopia-permission-denied', {'object' => $run}) unless $run->canview;
# Result is list of test cases for the given test run
return $run->plan;
}
sub lookup_environment_id_by_name {
return { ERROR => 'This method is considered harmful and has been deprecated. Please use Environment::check_environment instead'};
}
sub lookup_environment_name_by_id {
return { ERROR => 'This method has been deprecated. Please use Environment::get instead'};
}
sub add_tag {
my $self = shift;
my ($run_ids, $tags) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{run_ids} = shift;
$params->{tags} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($run_ids);
my @ids = Bugzilla::Extension::Testopia::Util::process_list($params->{run_ids});
my @results;
foreach my $id (@ids){
my $run = new Bugzilla::Extension::Testopia::TestRun($id);
unless ($run){
unless ($run->{run_id}){
push @results, {ERROR => "TestRun $id does not exist"};
next;
}
@ -325,7 +340,7 @@ sub add_tag {
next;
}
eval {
$run->add_tag($tags);
$run->add_tag($params->{tags});
};
if ($@){
push @results, {ERROR => $@};
@ -337,16 +352,22 @@ sub add_tag {
sub remove_tag {
my $self = shift;
my ($run_id, $tag_name) = @_;
my ($params) = @_;
if (ref $params ne 'HASH'){
$params = {};
$params->{run_id} = shift;
$params->{tag} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my $run = new Bugzilla::Extension::Testopia::TestRun($run_id);
my $run = new Bugzilla::Extension::Testopia::TestRun($params->{run_id});
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Run', id => $run_id}) unless $run;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Run', id => $params->{run_id}}) unless $run->{run_id};
ThrowUserError('testopia-read-only', {'object' => $run}) unless $run->canedit;
$run->remove_tag($tag_name);
$run->remove_tag($params->{tag});
# Result 0 on success, otherwise an exception will be thrown
return 0;
@ -360,7 +381,7 @@ sub get_tags {
my $run = new Bugzilla::Extension::Testopia::TestRun($run_id);
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Run', id => $run_id}) unless $run;
ThrowUserError('invalid-test-id-non-existent', {type => 'Test Run', id => $run_id}) unless $run->{run_id};
ThrowUserError('testopia-permission-denied', {'object' => $run}) unless $run->canview;
my @results;
@ -373,21 +394,17 @@ sub get_tags {
sub get_completion_report {
my $self = shift;
my ($runs) = @_;
my ($params) = @_;
my $vars;
if (ref $params ne 'HASH'){
$params = {};
$params->{runs} = shift;
}
Bugzilla->login(LOGIN_REQUIRED);
my @run_ids;
if (ref $runs eq 'ARRAY'){
push @run_ids, @$runs
}
elsif ($runs =~ /,/){
push @run_ids, split(/[\s,]+/, $runs);
}
else{
push @run_ids, $runs;
}
my @run_ids = Bugzilla::Extension::Testopia::Util::process_list($params->{runs});
my @runs;
foreach my $g (@run_ids){
@ -430,10 +447,15 @@ sub get_completion_report {
sub get_bugs {
my $self = shift;
my ($runs) = @_;
my ($params) = @_;
my $dbh = Bugzilla->dbh;
my @run_ids = Bugzilla::Extension::Testopia::Util::process_list($runs);
if (ref $params ne 'HASH'){
$params = {};
$params->{runs} = shift;
}
my @run_ids = Bugzilla::Extension::Testopia::Util::process_list($params->{runs});
my $bugs = $dbh->selectcol_arrayref("
SELECT DISTINCT tcb.bug_id
@ -470,7 +492,7 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
=over
=item C<add_cases($case_ids, $run_ids)>
=item C<add_cases>
Description: Add one or more cases to the selected test runs.
@ -483,7 +505,7 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
Returns: Array: empty on success or an array of hashes with failure
codes if a failure occured.
=item C<add_tag($run_ids, $tags)>
=item C<add_tag>
Description: Add one or more tags to the selected test runs.
@ -496,7 +518,7 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
Returns: Array: empty on success or an array of hashes with failure
codes if a failure occured.
=item C<create($values)>
=item C<create>
Description: Creates a new Test Run object and stores it in the database.
@ -521,7 +543,7 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
Returns: The newly created object hash.
=item C<get($run_id)>
=item C<get>
Description: Used to load an existing test run from the database.
@ -529,7 +551,7 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
Returns: Hash: A blessed Bugzilla::Extension::Testopia::TestRun object hash
=item C<get_bugs($runs)>
=item C<get_bugs>
Description: Get the list of bugs attached to this run.
@ -538,15 +560,15 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
Returns: Array: An array of bug object hashes.
=item C<get_change_history($run_id)>
=item C<get_change_history>
Description: Get the list of changes to the fields of this run.
Params: $run_id - Integer: An integer representing the ID of the run in the database
Params: $id - Integer: An integer representing the ID of the run in the database
Returns: Array: An array of hashes with changed fields and their details.
=item C<get_completion_report($runs)>
=item C<get_completion_report>
Description: Get a report of the current status of the selected runs combined.
@ -557,19 +579,19 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
case-runs in the run. Counts only the most recently statused case-run
for a given build and environment.
=item C<get_tags($run_id)>
=item C<get_tags>
Description: Get the list of tags attached to this run.
Params: $run_id - Integer: An integer representing the ID of the run in the database
Params: $id - Integer: An integer representing the ID of the run in the database
Returns: Array: An array of tags .
=item C<get_test_case_runs($run_id, $current)>
=item C<get_test_case_runs>
Description: Get the list of cases that this run is linked to.
Params: $run_id - Integer: An integer representing the ID in the database
Params: $id - Integer: An integer representing the ID in the database
for this run.
$current - Boolean: 1 to only include the current set (what is displayed
@ -577,33 +599,33 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
Returns: Array: An array of test case-run object hashes.
=item C<get_test_cases($run_id)>
=item C<get_test_cases>
Description: Get the list of cases that this run is linked to.
Params: $run_id - Integer: An integer representing the ID in the database
Params: $id - Integer: An integer representing the ID in the database
for this run.
Returns: Array: An array of test case object hashes.
=item C<get_case_tags($run_id)>
=item C<get_case_tags>
Description: Get the list of tags associated with the cases in this run.
Params: $run_id - Integer: An integer representing the ID of the run in the database
Params: $id - Integer: An integer representing the ID of the run in the database
Returns: Array: An array of tag object hashes.
=item C<get_test_plan($run_id)>
=item C<get_test_plan>
Description: Get the plan that this run is associated with.
Params: $run_id - Integer: An integer representing the ID in the database
Params: $id - Integer: An integer representing the ID in the database
for this run.
Returns: Hash: A plan object hash.
=item C<list($query)>
=item C<list>
Description: Performs a search and returns the resulting list of test runs.
@ -694,7 +716,7 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
Returns: Array: Matching test runs are retuned in a list of run object hashes.
=item C<list_count($query)>
=item C<list_count>
Description: Performs a search and returns the resulting count of runs.
@ -702,7 +724,7 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
Returns: Integer - total matching runs.
=item C<remove_tag($run_id, $tag)>
=item C<remove_tag>
Description: Remove a tag from a run.
@ -712,17 +734,18 @@ Provides methods for automated scripts to manipulate Testopia TestRuns
Returns: 0 on success.
=item C<update($ids, $values)>
=item C<update>
Description: Updates the fields of the selected test run.
Params: $ids - Integer: A single TestRun ID.
Params: $id - Integer: A single TestRun ID.
$values - Hash of keys matching TestRun fields and the new values
to set each field to. See L<create> for description
+-------------------+----------------+
| Field | Type |
+-------------------+----------------+
| id (readonly) | Integer |
| plan_id | Integer |
| environment | Integer/String |
| build | Integer/String |

View File

@ -33,7 +33,7 @@ use Bugzilla::Extension::Testopia::Constants;
sub api_version {
my $self = shift;
return "2.0";
return "2.1";
}
sub testopia_version {
@ -61,11 +61,11 @@ Provides information about this installation.
=over
=item C<api_version()>
=item C<api_version>
Description: Returns the API version.
=item C<testopia_version()>
=item C<testopia_version>
Description: Returns the version of Testopia on this server.

View File

@ -0,0 +1,106 @@
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# Contributor(s): Marc Schumann <wurblzap@gmail.com>
# Max Kanat-Alexander <mkanat@bugzilla.org>
# Mads Bondo Dydensborg <mbd@dbc.dk>
# Noura Elhawary <nelhawar@redhat.com>
package Bugzilla::Extension::Testopia::WebService::User;
use strict;
use base qw(Bugzilla::WebService);
use lib qw(./extensions/Testopia/lib);
use Bugzilla;
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::User;
#################
# User Lookup #
#################
sub lookup_login_by_id {
my $self = shift;
my ($params) = @_;
if ( !ref $params ) {
$params = {};
$params->{id} = $_[0];
}
my $user = new Bugzilla::User( $params->{id} );
my $result = defined $user ? $user->login : '';
# Result is user login string or empty string if failed
return $result;
}
sub lookup_id_by_login {
my $self = shift;
my ($params) = @_;
if ( !ref $params ) {
$params = {};
$params->{login} = $_[0];
}
my $result = Bugzilla::User::login_to_id( $params->{login} );
# Result is user id or 0 if failed
return $result;
}
1;
__END__
=head1 NAME
Bugzilla::Testopia::Webservice::User - Lookup users by Id or Name
=head1 DESCRIPTION
Allows you to lookup users by login name (email) or ID
=head1 METHODS
See L<Bugzilla::WebService> for a description of how parameters are passed.
=over
=item lookup_status_name_by_id
Params: $id - Integer: ID of the status to return
Returns: String: the status name.
=item lookup_status_id_by_name
Params: $login - String: the status name.
Returns: Integer: ID of the status.
=back
=head1 SEE ALSO
L<Bugzilla::Extension::Testopia::TestCaseRun>
L<Bugzilla::Webservice>
=head1 AUTHOR
Greg Hendricks <ghendricks@novell.com>

View File

@ -1,287 +0,0 @@
Index: Bugzilla/WebService/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/WebService/User.pm,v
retrieving revision 1.6.2.2
diff -u -r1.6.2.2 User.pm
--- Bugzilla/WebService/User.pm 26 Nov 2008 01:24:15 -0000 1.6.2.2
+++ Bugzilla/WebService/User.pm 18 Dec 2008 22:33:02 -0000
@@ -125,6 +125,32 @@
return { id => type('int')->value($user->id) };
}
+#################
+# User Lookup #
+#################
+
+sub lookup_login_by_id {
+ my $self = shift;
+ my ($author_id) = @_;
+
+ my $user = new Bugzilla::User($author_id);
+
+ my $result = defined $user ? $user->login : '';
+
+ # Result is user login string or empty string if failed
+ return $result;
+}
+
+sub lookup_id_by_login {
+ my $self = shift;
+ my ($author) = @_;
+
+ my $result = Bugzilla::User::login_to_id($author);
+
+ # Result is user id or 0 if failed
+ return $result;
+}
+
1;
__END__
Index: Bugzilla/Constants.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Constants.pm,v
retrieving revision 1.92.2.7
diff -u -r1.92.2.7 Constants.pm
--- Bugzilla/Constants.pm 30 Nov 2008 01:34:57 -0000 1.92.2.7
+++ Bugzilla/Constants.pm 18 Dec 2008 22:33:01 -0000
@@ -131,6 +131,7 @@
ERROR_MODE_WEBPAGE
ERROR_MODE_DIE
ERROR_MODE_DIE_SOAP_FAULT
+ ERROR_MODE_AJAX
INSTALLATION_MODE_INTERACTIVE
INSTALLATION_MODE_NON_INTERACTIVE
@@ -370,6 +371,7 @@
use constant ERROR_MODE_WEBPAGE => 0;
use constant ERROR_MODE_DIE => 1;
use constant ERROR_MODE_DIE_SOAP_FAULT => 2;
+use constant ERROR_MODE_AJAX => 3;
# The various modes that checksetup.pl can run in.
use constant INSTALLATION_MODE_INTERACTIVE => 0;
Index: Bugzilla/Bug.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Bug.pm,v
retrieving revision 1.241.2.18
diff -u -r1.241.2.18 Bug.pm
--- Bugzilla/Bug.pm 19 Nov 2008 19:32:57 -0000 1.241.2.18
+++ Bugzilla/Bug.pm 18 Dec 2008 22:33:01 -0000
@@ -2709,6 +2709,14 @@
"SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias);
}
+sub get_test_case_count {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ my $row_count = $dbh->selectall_arrayref(
+ "SELECT DISTINCT case_id FROM test_case_bugs WHERE bug_id = ?",
+ undef, $self->bug_id);
+ return scalar @$row_count;
+}
#####################################################################
# Subroutines
#####################################################################
Index: Bugzilla/Error.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Error.pm,v
retrieving revision 1.23.2.1
diff -u -r1.23.2.1 Error.pm
--- Bugzilla/Error.pm 27 May 2008 22:11:56 -0000 1.23.2.1
+++ Bugzilla/Error.pm 18 Dec 2008 22:33:01 -0000
@@ -32,6 +32,7 @@
use Bugzilla::WebService::Constants;
use Bugzilla::Util;
use Date::Format;
+use JSON;
# We cannot use $^S to detect if we are in an eval(), because mod_perl
# already eval'uates everything, so $^S = 1 in all cases under mod_perl!
@@ -114,6 +115,16 @@
}
die SOAP::Fault->faultcode($code)->faultstring($message);
}
+ elsif (Bugzilla->error_mode == ERROR_MODE_AJAX) {
+ # JSON can't handle strings across lines.
+ $message =~ s/\n/ /gm;
+ my $err;
+ $err->{'success'} = JSON::false;
+ $err->{'error'} = $error;
+ $err->{'message'} = $message;
+ my $json = new JSON;
+ print $json->encode($err);
+ }
}
exit;
}
Index: Bugzilla/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/User.pm,v
retrieving revision 1.164.2.4
diff -u -r1.164.2.4 User.pm
--- Bugzilla/User.pm 8 Nov 2008 19:03:32 -0000 1.164.2.4
+++ Bugzilla/User.pm 18 Dec 2008 22:33:02 -0000
@@ -335,6 +335,16 @@
return $self->{queries_available};
}
+sub testopia_queries {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ my $ref = $dbh->selectall_arrayref(
+ "SELECT name, query FROM test_named_queries
+ WHERE userid = ? AND isvisible = 1",
+ {'Slice' =>{}}, $self->id);
+ return $ref;
+}
+
sub settings {
my ($self) = @_;
@@ -632,7 +642,7 @@
my $class_restricted = Bugzilla->params->{'useclassification'} && $class_id;
if (!defined $self->{selectable_products}) {
- my $query = "SELECT id " .
+ my $query = "(SELECT id, name AS pname " .
" FROM products " .
"LEFT JOIN group_control_map " .
" ON group_control_map.product_id = products.id ";
@@ -642,10 +652,17 @@
$query .= " AND group_control_map.membercontrol = " . CONTROLMAPMANDATORY;
}
$query .= " AND group_id NOT IN(" . $self->groups_as_string . ") " .
- " WHERE group_id IS NULL " .
- "ORDER BY name";
+ " WHERE group_id IS NULL) " ;
+
- my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query);
+ $query .= "UNION (SELECT id, tr_products.name AS pname FROM products AS tr_products ".
+ "INNER JOIN test_plans ON tr_products.id = test_plans.product_id ".
+ "INNER JOIN test_plan_permissions ON test_plan_permissions.plan_id = test_plans.plan_id ".
+ "WHERE test_plan_permissions.userid = ?)";
+
+ $query .= "ORDER BY pname ";
+
+ my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query,undef,$self->id);
$self->{selectable_products} = Bugzilla::Product->new_from_list($prod_ids);
}
@@ -925,6 +942,33 @@
$group_delete->execute($id, $group, GRANT_REGEXP) if $present;
}
}
+ # Now do the same for Testopia test plans.
+ $sth = $dbh->prepare("SELECT test_plan_permissions_regexp.plan_id,
+ user_regexp, test_plan_permissions_regexp.permissions,
+ test_plan_permissions.plan_id
+ FROM test_plan_permissions_regexp
+ LEFT JOIN test_plan_permissions
+ ON test_plan_permissions_regexp.plan_id = test_plan_permissions.plan_id
+ AND test_plan_permissions.userid = ?
+ AND test_plan_permissions.grant_type = ?");
+
+ $sth->execute($id, GRANT_REGEXP);
+ my $plan_insert = $dbh->prepare(q{INSERT INTO test_plan_permissions
+ (userid, plan_id, permissions, grant_type)
+ VALUES (?, ?, ?, ?)});
+ my $plan_delete = $dbh->prepare(q{DELETE FROM test_plan_permissions
+ WHERE userid = ?
+ AND plan_id = ?
+ AND grant_type = ?});
+
+ while (my ($planid, $regexp, $perms, $present) = $sth->fetchrow_array()) {
+ if (($regexp ne '') && ($self->{login} =~ m/$regexp/i)) {
+ $plan_insert->execute($id, $planid, $perms, GRANT_REGEXP) unless $present;
+ } else {
+ $plan_delete->execute($id, $planid, GRANT_REGEXP) if $present;
+ }
+ }
+
}
sub product_responsibilities {
Index: Bugzilla/DB/Mysql.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/DB/Mysql.pm,v
retrieving revision 1.60.2.7
diff -u -r1.60.2.7 Mysql.pm
--- Bugzilla/DB/Mysql.pm 7 Nov 2008 00:10:15 -0000 1.60.2.7
+++ Bugzilla/DB/Mysql.pm 18 Dec 2008 22:33:02 -0000
@@ -690,6 +690,9 @@
$self->bz_drop_index('bugs_fulltext', $index);
}
}
+ if ($table eq 'test_runs' && $name eq 'summary') {
+ $self->bz_drop_index('test_runs', 'test_runs_summary_idx');
+ }
print "Converting $table.$name to be stored as UTF-8...\n";
my $col_info =
Index: Bugzilla/Install/Filesystem.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Install/Filesystem.pm,v
retrieving revision 1.29.2.1
diff -u -r1.29.2.1 Filesystem.pm
--- Bugzilla/Install/Filesystem.pm 13 Jun 2008 20:58:47 -0000 1.29.2.1
+++ Bugzilla/Install/Filesystem.pm 18 Dec 2008 22:33:02 -0000
@@ -111,6 +111,8 @@
'runtests.pl' => { perms => $owner_executable },
'testserver.pl' => { perms => $ws_executable },
'whine.pl' => { perms => $ws_executable },
+ 'tr_csv2xml.pl' => { perms => $ws_executable },
+ 'tr_importxml.pl' => { perms => $ws_executable },
'customfield.pl' => { perms => $owner_executable },
'email_in.pl' => { perms => $ws_executable },
'sanitycheck.pl' => { perms => $ws_executable },
@@ -157,6 +159,8 @@
dirs => $ws_dir_readable },
$extlib => { files => $ws_readable,
dirs => $ws_dir_readable },
+ "$libdir/testopia" => { files => $ws_readable,
+ dirs => $ws_dir_readable },
$templatedir => { files => $ws_readable,
dirs => $ws_dir_readable },
$extensionsdir => { files => $ws_readable,
@@ -171,6 +175,8 @@
dirs => $ws_dir_readable },
t => { files => $owner_readable,
dirs => $owner_dir_readable },
+ 'testopia/t' => { files => $owner_readable,
+ dirs => $owner_dir_readable },
'docs/*/html' => { files => $ws_readable,
dirs => $ws_dir_readable },
'docs/*/pdf' => { files => $ws_readable,
Index: template/en/default/admin/products/confirm-delete.html.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/admin/products/confirm-delete.html.tmpl,v
retrieving revision 1.9
diff -u -r1.9 confirm-delete.html.tmpl
--- template/en/default/admin/products/confirm-delete.html.tmpl 7 Oct 2007 23:18:29 -0000 1.9
+++ template/en/default/admin/products/confirm-delete.html.tmpl 18 Dec 2008 22:33:02 -0000
@@ -255,6 +255,8 @@
[% END %]
+[% Hook.process("additional-product-values") %]
+
[% IF product.bug_count == 0 || Param('allowbugdeletion') %]
<p>Do you really want to delete this product?</p>
Index: template/en/default/global/setting-descs.none.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/global/setting-descs.none.tmpl,v
retrieving revision 1.14
diff -u -r1.14 setting-descs.none.tmpl
--- template/en/default/global/setting-descs.none.tmpl 20 Aug 2007 18:25:04 -0000 1.14
+++ template/en/default/global/setting-descs.none.tmpl 18 Dec 2008 22:33:02 -0000
@@ -40,6 +40,7 @@
"never" => "Never",
"cc_unless_role" => "Only if I have no role on them",
"lang" => "Language used in email",
+ "view_testopia" => "View the Testopia links",
"quote_replies" => "Quote the associated comment when you click on its reply link",
"quoted_reply" => "Quote the full comment",
"simple_reply" => "Reference the comment number only",

View File

@ -1,290 +0,0 @@
### Eclipse Workspace Patch 1.0
#P bmo-3.4
Index: Bugzilla/Constants.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Constants.pm,v
retrieving revision 1.109.2.12
diff -u -r1.109.2.12 Constants.pm
--- Bugzilla/Constants.pm 5 Nov 2009 18:56:34 -0000 1.109.2.12
+++ Bugzilla/Constants.pm 7 Nov 2009 02:55:47 -0000
@@ -134,6 +134,7 @@
ERROR_MODE_WEBPAGE
ERROR_MODE_DIE
ERROR_MODE_DIE_SOAP_FAULT
+ ERROR_MODE_AJAX
INSTALLATION_MODE_INTERACTIVE
INSTALLATION_MODE_NON_INTERACTIVE
@@ -386,6 +387,7 @@
use constant ERROR_MODE_WEBPAGE => 0;
use constant ERROR_MODE_DIE => 1;
use constant ERROR_MODE_DIE_SOAP_FAULT => 2;
+use constant ERROR_MODE_AJAX => 3;
# The various modes that checksetup.pl can run in.
use constant INSTALLATION_MODE_INTERACTIVE => 0;
Index: Bugzilla/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/User.pm,v
retrieving revision 1.178.2.3
diff -u -r1.178.2.3 User.pm
--- Bugzilla/User.pm 2 Jun 2009 22:04:13 -0000 1.178.2.3
+++ Bugzilla/User.pm 7 Nov 2009 02:55:48 -0000
@@ -339,6 +339,16 @@
return $self->{queries_available};
}
+sub testopia_queries {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ my $ref = $dbh->selectall_arrayref(
+ "SELECT name, query FROM test_named_queries
+ WHERE userid = ? AND isvisible = 1",
+ {'Slice' =>{}}, $self->id);
+ return $ref;
+}
+
sub settings {
my ($self) = @_;
@@ -657,7 +667,7 @@
my $class_restricted = Bugzilla->params->{'useclassification'} && $class_id;
if (!defined $self->{selectable_products}) {
- my $query = "SELECT id " .
+ my $query = "(SELECT id, name AS pname " .
" FROM products " .
"LEFT JOIN group_control_map " .
" ON group_control_map.product_id = products.id ";
@@ -667,10 +677,17 @@
$query .= " AND group_control_map.membercontrol = " . CONTROLMAPMANDATORY;
}
$query .= " AND group_id NOT IN(" . $self->groups_as_string . ") " .
- " WHERE group_id IS NULL " .
- "ORDER BY name";
+ " WHERE group_id IS NULL) " ;
+
- my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query);
+ $query .= "UNION (SELECT id, tr_products.name AS pname FROM products AS tr_products ".
+ "INNER JOIN test_plans ON tr_products.id = test_plans.product_id ".
+ "INNER JOIN test_plan_permissions ON test_plan_permissions.plan_id = test_plans.plan_id ".
+ "WHERE test_plan_permissions.userid = ?)";
+
+ $query .= "ORDER BY pname ";
+
+ my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query,undef,$self->id);
$self->{selectable_products} = Bugzilla::Product->new_from_list($prod_ids);
}
@@ -948,6 +965,33 @@
$group_delete->execute($id, $group, GRANT_REGEXP) if $present;
}
}
+ # Now do the same for Testopia test plans.
+ $sth = $dbh->prepare("SELECT test_plan_permissions_regexp.plan_id,
+ user_regexp, test_plan_permissions_regexp.permissions,
+ test_plan_permissions.plan_id
+ FROM test_plan_permissions_regexp
+ LEFT JOIN test_plan_permissions
+ ON test_plan_permissions_regexp.plan_id = test_plan_permissions.plan_id
+ AND test_plan_permissions.userid = ?
+ AND test_plan_permissions.grant_type = ?");
+
+ $sth->execute($id, GRANT_REGEXP);
+ my $plan_insert = $dbh->prepare(q{INSERT INTO test_plan_permissions
+ (userid, plan_id, permissions, grant_type)
+ VALUES (?, ?, ?, ?)});
+ my $plan_delete = $dbh->prepare(q{DELETE FROM test_plan_permissions
+ WHERE userid = ?
+ AND plan_id = ?
+ AND grant_type = ?});
+
+ while (my ($planid, $regexp, $perms, $present) = $sth->fetchrow_array()) {
+ if (($regexp ne '') && ($self->{login} =~ m/$regexp/i)) {
+ $plan_insert->execute($id, $planid, $perms, GRANT_REGEXP) unless $present;
+ } else {
+ $plan_delete->execute($id, $planid, GRANT_REGEXP) if $present;
+ }
+ }
+
}
sub product_responsibilities {
Index: Bugzilla/Bug.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Bug.pm,v
retrieving revision 1.276.2.12
diff -u -r1.276.2.12 Bug.pm
--- Bugzilla/Bug.pm 1 Nov 2009 20:14:11 -0000 1.276.2.12
+++ Bugzilla/Bug.pm 7 Nov 2009 02:55:46 -0000
@@ -2939,6 +2939,14 @@
"SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias);
}
+sub get_test_case_count {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ my $row_count = $dbh->selectall_arrayref(
+ "SELECT DISTINCT case_id FROM test_case_bugs WHERE bug_id = ?",
+ undef, $self->bug_id);
+ return scalar @$row_count;
+}
#####################################################################
# Subroutines
#####################################################################
Index: Bugzilla/Error.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Error.pm,v
retrieving revision 1.24
diff -u -r1.24 Error.pm
--- Bugzilla/Error.pm 27 May 2008 22:08:59 -0000 1.24
+++ Bugzilla/Error.pm 7 Nov 2009 02:55:47 -0000
@@ -32,6 +32,7 @@
use Bugzilla::WebService::Constants;
use Bugzilla::Util;
use Date::Format;
+use JSON;
# We cannot use $^S to detect if we are in an eval(), because mod_perl
# already eval'uates everything, so $^S = 1 in all cases under mod_perl!
@@ -114,6 +115,16 @@
}
die SOAP::Fault->faultcode($code)->faultstring($message);
}
+ elsif (Bugzilla->error_mode == ERROR_MODE_AJAX) {
+ # JSON can't handle strings across lines.
+ $message =~ s/\n/ /gm;
+ my $err;
+ $err->{'success'} = JSON::false;
+ $err->{'error'} = $error;
+ $err->{'message'} = $message;
+ my $json = new JSON;
+ print $json->encode($err);
+ }
}
exit;
}
Index: Bugzilla/Search.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Search.pm,v
retrieving revision 1.173.2.1
diff -u -r1.173.2.1 Search.pm
--- Bugzilla/Search.pm 7 Jul 2009 18:20:08 -0000 1.173.2.1
+++ Bugzilla/Search.pm 7 Nov 2009 02:55:47 -0000
@@ -269,6 +269,12 @@
push(@supptables, "LEFT JOIN longdescs AS ldtime " .
"ON ldtime.bug_id = bugs.bug_id");
}
+ ### Testopia ###
+ if (grep($_ eq 'test_cases', @fields)){
+ push(@supptables, "LEFT JOIN test_case_bugs AS tcb " .
+ "ON bugs.bug_id = tcb.bug_id ");
+ }
+ ### end Testopia ###
my $minvotes;
if (defined $params->param('votes')) {
Index: Bugzilla/DB/Mysql.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/DB/Mysql.pm,v
retrieving revision 1.72.2.3
diff -u -r1.72.2.3 Mysql.pm
--- Bugzilla/DB/Mysql.pm 20 Sep 2009 22:33:59 -0000 1.72.2.3
+++ Bugzilla/DB/Mysql.pm 7 Nov 2009 02:55:49 -0000
@@ -746,6 +746,9 @@
$self->bz_drop_index('bugs_fulltext', $index);
}
}
+ if ($table eq 'test_runs' && $name eq 'summary') {
+ $self->bz_drop_index('test_runs', 'test_runs_summary_idx');
+ }
my $dropped = $self->bz_drop_related_fks($table, $name);
push(@dropped_fks, @$dropped);
Index: template/en/default/admin/products/confirm-delete.html.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/admin/products/confirm-delete.html.tmpl,v
retrieving revision 1.11
diff -u -r1.11 confirm-delete.html.tmpl
--- template/en/default/admin/products/confirm-delete.html.tmpl 18 Dec 2008 17:18:20 -0000 1.11
+++ template/en/default/admin/products/confirm-delete.html.tmpl 7 Nov 2009 02:55:49 -0000
@@ -243,6 +243,8 @@
[% Hook.process("confirmation") %]
+[% Hook.process("additional-product-values") %]
+
[% IF product.bug_count == 0 || Param('allowbugdeletion') %]
<p>Do you really want to delete this product?</p>
Index: template/en/default/global/setting-descs.none.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/global/setting-descs.none.tmpl,v
retrieving revision 1.15.2.1
diff -u -r1.15.2.1 setting-descs.none.tmpl
--- template/en/default/global/setting-descs.none.tmpl 19 Aug 2009 21:41:45 -0000 1.15.2.1
+++ template/en/default/global/setting-descs.none.tmpl 7 Nov 2009 02:55:49 -0000
@@ -40,6 +40,7 @@
"never" => "Never",
"cc_unless_role" => "Only if I have no role on them",
"lang" => "Language used in email",
+ "view_testopia" => "View the Testopia links",
"quote_replies" => "Quote the associated comment when you click on its reply link",
"quoted_reply" => "Quote the full comment",
"simple_reply" => "Reference the comment number only",
Index: Bugzilla/Install/Filesystem.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Install/Filesystem.pm,v
retrieving revision 1.34
diff -u -r1.34 Filesystem.pm
--- Bugzilla/Install/Filesystem.pm 23 Jan 2009 21:34:42 -0000 1.34
+++ Bugzilla/Install/Filesystem.pm 7 Nov 2009 02:55:49 -0000
@@ -112,6 +112,7 @@
'runtests.pl' => { perms => $owner_executable },
'testserver.pl' => { perms => $ws_executable },
'whine.pl' => { perms => $ws_executable },
+ 'tr_importxml.pl' => { perms => $ws_executable },
'customfield.pl' => { perms => $owner_executable },
'email_in.pl' => { perms => $ws_executable },
'sanitycheck.pl' => { perms => $ws_executable },
Index: Bugzilla/WebService/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/WebService/User.pm,v
retrieving revision 1.14
diff -u -r1.14 User.pm
--- Bugzilla/WebService/User.pm 26 Jan 2009 20:40:22 -0000 1.14
+++ Bugzilla/WebService/User.pm 7 Nov 2009 02:55:49 -0000
@@ -223,6 +223,32 @@
return { users => \@users };
}
+#################
+# User Lookup #
+#################
+
+sub lookup_login_by_id {
+ my $self = shift;
+ my ($author_id) = @_;
+
+ my $user = new Bugzilla::User($author_id);
+
+ my $result = defined $user ? $user->login : '';
+
+ # Result is user login string or empty string if failed
+ return $result;
+}
+
+sub lookup_id_by_login {
+ my $self = shift;
+ my ($author) = @_;
+
+ my $result = Bugzilla::User::login_to_id($author);
+
+ # Result is user id or 0 if failed
+ return $result;
+}
+
1;
__END__

View File

@ -1,290 +0,0 @@
### Eclipse Workspace Patch 1.0
#P bmo-3.4
Index: Bugzilla/Constants.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Constants.pm,v
retrieving revision 1.109.2.12
diff -u -r1.109.2.12 Constants.pm
--- Bugzilla/Constants.pm 5 Nov 2009 18:56:34 -0000 1.109.2.12
+++ Bugzilla/Constants.pm 7 Nov 2009 02:55:47 -0000
@@ -134,6 +134,7 @@
ERROR_MODE_WEBPAGE
ERROR_MODE_DIE
ERROR_MODE_DIE_SOAP_FAULT
+ ERROR_MODE_AJAX
INSTALLATION_MODE_INTERACTIVE
INSTALLATION_MODE_NON_INTERACTIVE
@@ -386,6 +387,7 @@
use constant ERROR_MODE_WEBPAGE => 0;
use constant ERROR_MODE_DIE => 1;
use constant ERROR_MODE_DIE_SOAP_FAULT => 2;
+use constant ERROR_MODE_AJAX => 3;
# The various modes that checksetup.pl can run in.
use constant INSTALLATION_MODE_INTERACTIVE => 0;
Index: Bugzilla/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/User.pm,v
retrieving revision 1.178.2.3
diff -u -r1.178.2.3 User.pm
--- Bugzilla/User.pm 2 Jun 2009 22:04:13 -0000 1.178.2.3
+++ Bugzilla/User.pm 7 Nov 2009 02:55:48 -0000
@@ -339,6 +339,16 @@
return $self->{queries_available};
}
+sub testopia_queries {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ my $ref = $dbh->selectall_arrayref(
+ "SELECT name, query FROM test_named_queries
+ WHERE userid = ? AND isvisible = 1",
+ {'Slice' =>{}}, $self->id);
+ return $ref;
+}
+
sub settings {
my ($self) = @_;
@@ -657,7 +667,7 @@
my $class_restricted = Bugzilla->params->{'useclassification'} && $class_id;
if (!defined $self->{selectable_products}) {
- my $query = "SELECT id " .
+ my $query = "(SELECT id, name AS pname " .
" FROM products " .
"LEFT JOIN group_control_map " .
" ON group_control_map.product_id = products.id ";
@@ -667,10 +677,17 @@
$query .= " AND group_control_map.membercontrol = " . CONTROLMAPMANDATORY;
}
$query .= " AND group_id NOT IN(" . $self->groups_as_string . ") " .
- " WHERE group_id IS NULL " .
- "ORDER BY name";
+ " WHERE group_id IS NULL) " ;
+
- my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query);
+ $query .= "UNION (SELECT id, tr_products.name AS pname FROM products AS tr_products ".
+ "INNER JOIN test_plans ON tr_products.id = test_plans.product_id ".
+ "INNER JOIN test_plan_permissions ON test_plan_permissions.plan_id = test_plans.plan_id ".
+ "WHERE test_plan_permissions.userid = ?)";
+
+ $query .= "ORDER BY pname ";
+
+ my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query,undef,$self->id);
$self->{selectable_products} = Bugzilla::Product->new_from_list($prod_ids);
}
@@ -948,6 +965,33 @@
$group_delete->execute($id, $group, GRANT_REGEXP) if $present;
}
}
+ # Now do the same for Testopia test plans.
+ $sth = $dbh->prepare("SELECT test_plan_permissions_regexp.plan_id,
+ user_regexp, test_plan_permissions_regexp.permissions,
+ test_plan_permissions.plan_id
+ FROM test_plan_permissions_regexp
+ LEFT JOIN test_plan_permissions
+ ON test_plan_permissions_regexp.plan_id = test_plan_permissions.plan_id
+ AND test_plan_permissions.userid = ?
+ AND test_plan_permissions.grant_type = ?");
+
+ $sth->execute($id, GRANT_REGEXP);
+ my $plan_insert = $dbh->prepare(q{INSERT INTO test_plan_permissions
+ (userid, plan_id, permissions, grant_type)
+ VALUES (?, ?, ?, ?)});
+ my $plan_delete = $dbh->prepare(q{DELETE FROM test_plan_permissions
+ WHERE userid = ?
+ AND plan_id = ?
+ AND grant_type = ?});
+
+ while (my ($planid, $regexp, $perms, $present) = $sth->fetchrow_array()) {
+ if (($regexp ne '') && ($self->{login} =~ m/$regexp/i)) {
+ $plan_insert->execute($id, $planid, $perms, GRANT_REGEXP) unless $present;
+ } else {
+ $plan_delete->execute($id, $planid, GRANT_REGEXP) if $present;
+ }
+ }
+
}
sub product_responsibilities {
Index: Bugzilla/Bug.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Bug.pm,v
retrieving revision 1.276.2.12
diff -u -r1.276.2.12 Bug.pm
--- Bugzilla/Bug.pm 1 Nov 2009 20:14:11 -0000 1.276.2.12
+++ Bugzilla/Bug.pm 7 Nov 2009 02:55:46 -0000
@@ -2939,6 +2939,14 @@
"SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias);
}
+sub get_test_case_count {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ my $row_count = $dbh->selectall_arrayref(
+ "SELECT DISTINCT case_id FROM test_case_bugs WHERE bug_id = ?",
+ undef, $self->bug_id);
+ return scalar @$row_count;
+}
#####################################################################
# Subroutines
#####################################################################
Index: Bugzilla/Error.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Error.pm,v
retrieving revision 1.24
diff -u -r1.24 Error.pm
--- Bugzilla/Error.pm 27 May 2008 22:08:59 -0000 1.24
+++ Bugzilla/Error.pm 7 Nov 2009 02:55:47 -0000
@@ -32,6 +32,7 @@
use Bugzilla::WebService::Constants;
use Bugzilla::Util;
use Date::Format;
+use JSON;
# We cannot use $^S to detect if we are in an eval(), because mod_perl
# already eval'uates everything, so $^S = 1 in all cases under mod_perl!
@@ -114,6 +115,16 @@
}
die SOAP::Fault->faultcode($code)->faultstring($message);
}
+ elsif (Bugzilla->error_mode == ERROR_MODE_AJAX) {
+ # JSON can't handle strings across lines.
+ $message =~ s/\n/ /gm;
+ my $err;
+ $err->{'success'} = JSON::false;
+ $err->{'error'} = $error;
+ $err->{'message'} = $message;
+ my $json = new JSON;
+ print $json->encode($err);
+ }
}
exit;
}
Index: Bugzilla/Search.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Search.pm,v
retrieving revision 1.173.2.1
diff -u -r1.173.2.1 Search.pm
--- Bugzilla/Search.pm 7 Jul 2009 18:20:08 -0000 1.173.2.1
+++ Bugzilla/Search.pm 7 Nov 2009 02:55:47 -0000
@@ -269,6 +269,12 @@
push(@supptables, "LEFT JOIN longdescs AS ldtime " .
"ON ldtime.bug_id = bugs.bug_id");
}
+ ### Testopia ###
+ if (grep($_ eq 'test_cases', @fields)){
+ push(@supptables, "LEFT JOIN test_case_bugs AS tcb " .
+ "ON bugs.bug_id = tcb.bug_id ");
+ }
+ ### end Testopia ###
my $minvotes;
if (defined $params->param('votes')) {
Index: Bugzilla/DB/Mysql.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/DB/Mysql.pm,v
retrieving revision 1.72.2.3
diff -u -r1.72.2.3 Mysql.pm
--- Bugzilla/DB/Mysql.pm 20 Sep 2009 22:33:59 -0000 1.72.2.3
+++ Bugzilla/DB/Mysql.pm 7 Nov 2009 02:55:49 -0000
@@ -746,6 +746,9 @@
$self->bz_drop_index('bugs_fulltext', $index);
}
}
+ if ($table eq 'test_runs' && $name eq 'summary') {
+ $self->bz_drop_index('test_runs', 'test_runs_summary_idx');
+ }
my $dropped = $self->bz_drop_related_fks($table, $name);
push(@dropped_fks, @$dropped);
Index: template/en/default/admin/products/confirm-delete.html.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/admin/products/confirm-delete.html.tmpl,v
retrieving revision 1.11
diff -u -r1.11 confirm-delete.html.tmpl
--- template/en/default/admin/products/confirm-delete.html.tmpl 18 Dec 2008 17:18:20 -0000 1.11
+++ template/en/default/admin/products/confirm-delete.html.tmpl 7 Nov 2009 02:55:49 -0000
@@ -243,6 +243,8 @@
[% Hook.process("confirmation") %]
+[% Hook.process("additional-product-values") %]
+
[% IF product.bug_count == 0 || Param('allowbugdeletion') %]
<p>Do you really want to delete this product?</p>
Index: template/en/default/global/setting-descs.none.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/global/setting-descs.none.tmpl,v
retrieving revision 1.15.2.1
diff -u -r1.15.2.1 setting-descs.none.tmpl
--- template/en/default/global/setting-descs.none.tmpl 19 Aug 2009 21:41:45 -0000 1.15.2.1
+++ template/en/default/global/setting-descs.none.tmpl 7 Nov 2009 02:55:49 -0000
@@ -40,6 +40,7 @@
"never" => "Never",
"cc_unless_role" => "Only if I have no role on them",
"lang" => "Language used in email",
+ "view_testopia" => "View the Testopia links",
"quote_replies" => "Quote the associated comment when you click on its reply link",
"quoted_reply" => "Quote the full comment",
"simple_reply" => "Reference the comment number only",
Index: Bugzilla/Install/Filesystem.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Install/Filesystem.pm,v
retrieving revision 1.34
diff -u -r1.34 Filesystem.pm
--- Bugzilla/Install/Filesystem.pm 23 Jan 2009 21:34:42 -0000 1.34
+++ Bugzilla/Install/Filesystem.pm 7 Nov 2009 02:55:49 -0000
@@ -112,6 +112,7 @@
'runtests.pl' => { perms => $owner_executable },
'testserver.pl' => { perms => $ws_executable },
'whine.pl' => { perms => $ws_executable },
+ 'tr_importxml.pl' => { perms => $ws_executable },
'customfield.pl' => { perms => $owner_executable },
'email_in.pl' => { perms => $ws_executable },
'sanitycheck.pl' => { perms => $ws_executable },
Index: Bugzilla/WebService/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/WebService/User.pm,v
retrieving revision 1.14
diff -u -r1.14 User.pm
--- Bugzilla/WebService/User.pm 26 Jan 2009 20:40:22 -0000 1.14
+++ Bugzilla/WebService/User.pm 7 Nov 2009 02:55:49 -0000
@@ -223,6 +223,32 @@
return { users => \@users };
}
+#################
+# User Lookup #
+#################
+
+sub lookup_login_by_id {
+ my $self = shift;
+ my ($author_id) = @_;
+
+ my $user = new Bugzilla::User($author_id);
+
+ my $result = defined $user ? $user->login : '';
+
+ # Result is user login string or empty string if failed
+ return $result;
+}
+
+sub lookup_id_by_login {
+ my $self = shift;
+ my ($author) = @_;
+
+ my $result = Bugzilla::User::login_to_id($author);
+
+ # Result is user id or 0 if failed
+ return $result;
+}
+
1;
__END__

View File

@ -1,11 +1,7 @@
Index: Bugzilla/Bug.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Bug.pm,v
retrieving revision 1.308.2.7
diff -u -r1.308.2.7 Bug.pm
--- Bugzilla/Bug.pm 14 May 2010 12:32:53 -0000 1.308.2.7
+++ Bugzilla/Bug.pm 6 Jul 2010 19:22:46 -0000
@@ -3046,6 +3046,14 @@
=== modified file 'Bugzilla/Bug.pm'
--- Bugzilla/Bug.pm 2010-04-06 03:21:50 +0000
+++ Bugzilla/Bug.pm 2010-07-21 15:58:46 +0000
@@ -3044,6 +3044,14 @@
"SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias);
}
@ -20,13 +16,10 @@ diff -u -r1.308.2.7 Bug.pm
#####################################################################
# Subroutines
#####################################################################
Index: Bugzilla/Constants.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Constants.pm,v
retrieving revision 1.126.2.8
diff -u -r1.126.2.8 Constants.pm
--- Bugzilla/Constants.pm 24 Jun 2010 20:47:41 -0000 1.126.2.8
+++ Bugzilla/Constants.pm 6 Jul 2010 19:21:54 -0000
=== modified file 'Bugzilla/Constants.pm'
--- Bugzilla/Constants.pm 2010-04-13 04:53:30 +0000
+++ Bugzilla/Constants.pm 2010-07-21 15:58:46 +0000
@@ -140,6 +140,7 @@
ERROR_MODE_WEBPAGE
ERROR_MODE_DIE
@ -35,7 +28,7 @@ diff -u -r1.126.2.8 Constants.pm
ERROR_MODE_JSON_RPC
INSTALLATION_MODE_INTERACTIVE
@@ -421,6 +422,7 @@
@@ -420,6 +421,7 @@
use constant ERROR_MODE_WEBPAGE => 0;
use constant ERROR_MODE_DIE => 1;
use constant ERROR_MODE_DIE_SOAP_FAULT => 2;
@ -43,13 +36,10 @@ diff -u -r1.126.2.8 Constants.pm
use constant ERROR_MODE_JSON_RPC => 3;
# The various modes that checksetup.pl can run in.
Index: Bugzilla/Error.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Error.pm,v
retrieving revision 1.27.2.3
diff -u -r1.27.2.3 Error.pm
--- Bugzilla/Error.pm 1 Apr 2010 01:17:35 -0000 1.27.2.3
+++ Bugzilla/Error.pm 6 Jul 2010 19:26:28 -0000
=== modified file 'Bugzilla/Error.pm'
--- Bugzilla/Error.pm 2010-04-01 01:06:03 +0000
+++ Bugzilla/Error.pm 2010-07-21 15:58:46 +0000
@@ -32,6 +32,7 @@
use Bugzilla::WebService::Constants;
use Bugzilla::Util;
@ -75,13 +65,22 @@ diff -u -r1.27.2.3 Error.pm
}
exit;
}
Index: Bugzilla/Search.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Search.pm,v
retrieving revision 1.181.2.7
diff -u -r1.181.2.7 Search.pm
--- Bugzilla/Search.pm 24 Jun 2010 17:18:00 -0000 1.181.2.7
+++ Bugzilla/Search.pm 6 Jul 2010 19:25:28 -0000
=== modified file 'Bugzilla/Install/Filesystem.pm'
--- Bugzilla/Install/Filesystem.pm 2010-02-20 20:08:38 +0000
+++ Bugzilla/Install/Filesystem.pm 2010-07-21 15:58:46 +0000
@@ -122,6 +122,7 @@
'runtests.pl' => { perms => $owner_executable },
'testserver.pl' => { perms => $ws_executable },
'whine.pl' => { perms => $ws_executable },
+ 'tr_importxml.pl' => { perms => $ws_executable },
'customfield.pl' => { perms => $owner_executable },
'email_in.pl' => { perms => $ws_executable },
'sanitycheck.pl' => { perms => $ws_executable },
=== modified file 'Bugzilla/Search.pm'
--- Bugzilla/Search.pm 2010-03-29 21:17:54 +0000
+++ Bugzilla/Search.pm 2010-07-21 15:58:46 +0000
@@ -274,6 +274,12 @@
push(@supptables, "LEFT JOIN longdescs AS ldtime " .
"ON ldtime.bug_id = bugs.bug_id");
@ -95,13 +94,10 @@ diff -u -r1.181.2.7 Search.pm
if (grep($_ eq 'flagtypes.name', @fields)) {
push(@supptables, "LEFT JOIN flags ON flags.bug_id = bugs.bug_id AND attach_id IS NULL");
Index: Bugzilla/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/User.pm,v
retrieving revision 1.204.2.3
diff -u -r1.204.2.3 User.pm
--- Bugzilla/User.pm 18 Feb 2010 00:34:42 -0000 1.204.2.3
+++ Bugzilla/User.pm 6 Jul 2010 19:24:25 -0000
=== modified file 'Bugzilla/User.pm'
--- Bugzilla/User.pm 2010-02-18 00:16:31 +0000
+++ Bugzilla/User.pm 2010-07-21 15:58:46 +0000
@@ -361,6 +361,16 @@
return $self->{queries_available};
}
@ -132,6 +128,8 @@ diff -u -r1.204.2.3 User.pm
" AND group_id NOT IN(" . $self->groups_as_string . ") " .
- " WHERE group_id IS NULL " .
- "ORDER BY name";
-
- my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query);
+ " WHERE group_id IS NULL) " ;
+
+ $query .= "UNION (SELECT id, tr_products.name AS pname FROM products AS tr_products ".
@ -142,8 +140,7 @@ diff -u -r1.204.2.3 User.pm
+ $query .= "ORDER BY pname ";
+
+ my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query,undef,$self->id);
- my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query);
+
$self->{selectable_products} = Bugzilla::Product->new_from_list($prod_ids);
}
@ -181,40 +178,10 @@ diff -u -r1.204.2.3 User.pm
}
sub product_responsibilities {
Index: Bugzilla/Install/Filesystem.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Install/Filesystem.pm,v
retrieving revision 1.47.2.2
diff -u -r1.47.2.2 Filesystem.pm
--- Bugzilla/Install/Filesystem.pm 24 Jun 2010 17:10:19 -0000 1.47.2.2
+++ Bugzilla/Install/Filesystem.pm 7 Jul 2010 17:44:40 -0000
@@ -132,6 +132,7 @@
'runtests.pl' => { perms => $owner_executable },
'testserver.pl' => { perms => $ws_executable },
'whine.pl' => { perms => $ws_executable },
+ 'tr_importxml.pl' => { perms => $ws_executable },
'customfield.pl' => { perms => $owner_executable },
'email_in.pl' => { perms => $ws_executable },
'sanitycheck.pl' => { perms => $ws_executable },
Index: template/en/default/global/setting-descs.none.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/global/setting-descs.none.tmpl,v
retrieving revision 1.16
diff -u -r1.16 setting-descs.none.tmpl
--- template/en/default/global/setting-descs.none.tmpl 19 Aug 2009 21:40:07 -0000 1.16
+++ template/en/default/global/setting-descs.none.tmpl 7 Jul 2010 17:59:51 -0000
@@ -40,6 +40,7 @@
"never" => "Never",
"cc_unless_role" => "Only if I have no role on them",
"lang" => "Language used in email",
+ "view_testopia" => "View the Testopia links",
"quote_replies" => "Quote the associated comment when you click on its reply link",
"quoted_reply" => "Quote the full comment",
"simple_reply" => "Reference the comment number only",
Index: Bugzilla/WebService/Server/XMLRPC.pm
===================================================================
--- Bugzilla/WebService/Server/XMLRPC.pm 2010-03-10 20:52:02 +0000
+++ Bugzilla/WebService/Server/XMLRPC.pm 2010-07-08 18:17:14 +0000
=== modified file 'Bugzilla/WebService/Server/XMLRPC.pm'
--- Bugzilla/WebService/Server/XMLRPC.pm 2010-03-10 20:53:01 +0000
+++ Bugzilla/WebService/Server/XMLRPC.pm 2010-07-21 15:58:46 +0000
@@ -78,7 +78,10 @@
$som->{_bz_do_taint} = 1;
}
@ -227,4 +194,72 @@ Index: Bugzilla/WebService/Server/XMLRPC.pm
return $som;
}
@@ -149,13 +152,15 @@
sub paramsin {
my $self = shift;
- return $self->{bz_params_in} if $self->{bz_params_in};
- my $params = $self->SUPER::paramsin(@_);
- if ($self->{_bz_do_taint}) {
- taint_data($params);
+ if (!$self->{bz_params_in}) {
+ my @params = $self->SUPER::paramsin(@_);
+ if ($self->{_bz_do_taint}) {
+ taint_data(@params);
+ }
+ $self->{bz_params_in} = \@params;
}
- $self->{bz_params_in} = $params;
- return $self->{bz_params_in};
+ my $params = $self->{bz_params_in};
+ return wantarray ? @$params : $params->[0];
}
1;
=== modified file 'Bugzilla/WebService/Util.pm'
--- Bugzilla/WebService/Util.pm 2009-11-09 18:27:52 +0000
+++ Bugzilla/WebService/Util.pm 2010-07-21 15:58:46 +0000
@@ -52,13 +52,13 @@
}
sub taint_data {
- my $params = shift;
- return if !$params;
+ my @params = @_;
+ return if !@params;
# Though this is a private function, it hasn't changed since 2004 and
# should be safe to use, and prevents us from having to write it ourselves
# or require another module to do it.
- Test::Taint::_deeply_traverse(\&_delete_bad_keys, $params);
- Test::Taint::taint_deeply($params);
+ Test::Taint::_deeply_traverse(\&_delete_bad_keys, \@params);
+ Test::Taint::taint_deeply(\@params);
}
sub _delete_bad_keys {
@@ -79,6 +79,11 @@
sub validate {
my ($self, $params, @keys) = @_;
+
+ # If $params is defined but not a reference, then we weren't
+ # sent any parameters at all, and we're getting @keys where
+ # $params should be.
+ return ($self, undef) if (defined $params and !ref $params);
# If @keys is not empty then we convert any named
# parameters that have scalar values to arrayrefs
=== modified file 'template/en/default/global/setting-descs.none.tmpl'
--- template/en/default/global/setting-descs.none.tmpl 2009-08-19 21:40:07 +0000
+++ template/en/default/global/setting-descs.none.tmpl 2010-07-21 15:58:46 +0000
@@ -40,6 +40,7 @@
"never" => "Never",
"cc_unless_role" => "Only if I have no role on them",
"lang" => "Language used in email",
+ "view_testopia" => "View the Testopia links",
"quote_replies" => "Quote the associated comment when you click on its reply link",
"quoted_reply" => "Quote the full comment",
"simple_reply" => "Reference the comment number only",

View File

@ -1,34 +1,104 @@
Index: Bugzilla/Constants.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Constants.pm,v
retrieving revision 1.109.2.15
diff -u -r1.109.2.15 Constants.pm
--- Bugzilla/Constants.pm 1 Feb 2010 01:04:56 -0000 1.109.2.15
+++ Bugzilla/Constants.pm 4 Feb 2010 22:33:58 -0000
@@ -134,6 +134,7 @@
=== modified file 'Bugzilla/Bug.pm'
--- Bugzilla/Bug.pm 2010-05-14 12:25:20 +0000
+++ Bugzilla/Bug.pm 2010-07-21 16:00:58 +0000
@@ -3046,6 +3046,14 @@
"SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias);
}
+sub get_test_case_count {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ my $row_count = $dbh->selectall_arrayref(
+ "SELECT DISTINCT case_id FROM test_case_bugs WHERE bug_id = ?",
+ undef, $self->bug_id);
+ return scalar @$row_count;
+}
#####################################################################
# Subroutines
#####################################################################
=== modified file 'Bugzilla/Constants.pm'
--- Bugzilla/Constants.pm 2010-06-24 20:43:42 +0000
+++ Bugzilla/Constants.pm 2010-07-21 16:00:58 +0000
@@ -140,6 +140,7 @@
ERROR_MODE_WEBPAGE
ERROR_MODE_DIE
ERROR_MODE_DIE_SOAP_FAULT
+ ERROR_MODE_AJAX
ERROR_MODE_JSON_RPC
INSTALLATION_MODE_INTERACTIVE
INSTALLATION_MODE_NON_INTERACTIVE
@@ -386,6 +387,7 @@
@@ -421,6 +422,7 @@
use constant ERROR_MODE_WEBPAGE => 0;
use constant ERROR_MODE_DIE => 1;
use constant ERROR_MODE_DIE_SOAP_FAULT => 2;
+use constant ERROR_MODE_AJAX => 3;
+use constant ERROR_MODE_AJAX => 4;
use constant ERROR_MODE_JSON_RPC => 3;
# The various modes that checksetup.pl can run in.
use constant INSTALLATION_MODE_INTERACTIVE => 0;
Index: Bugzilla/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/User.pm,v
retrieving revision 1.178.2.3
diff -u -r1.178.2.3 User.pm
--- Bugzilla/User.pm 2 Jun 2009 22:04:13 -0000 1.178.2.3
+++ Bugzilla/User.pm 4 Feb 2010 22:33:58 -0000
@@ -339,6 +339,16 @@
=== modified file 'Bugzilla/Error.pm'
--- Bugzilla/Error.pm 2010-04-01 01:06:03 +0000
+++ Bugzilla/Error.pm 2010-07-21 16:00:58 +0000
@@ -32,6 +32,7 @@
use Bugzilla::WebService::Constants;
use Bugzilla::Util;
use Date::Format;
+use JSON;
# We cannot use $^S to detect if we are in an eval(), because mod_perl
# already eval'uates everything, so $^S = 1 in all cases under mod_perl!
@@ -135,6 +136,16 @@
$server->response($server->error_response_header);
}
}
+ elsif (Bugzilla->error_mode == ERROR_MODE_AJAX) {
+ # JSON can't handle strings across lines.
+ $message =~ s/\n/ /gm;
+ my $err;
+ $err->{'success'} = JSON::false;
+ $err->{'error'} = $error;
+ $err->{'message'} = $message;
+ my $json = new JSON;
+ print $json->encode($err);
+ }
}
exit;
}
=== modified file 'Bugzilla/Install/Filesystem.pm'
--- Bugzilla/Install/Filesystem.pm 2010-06-24 17:00:13 +0000
+++ Bugzilla/Install/Filesystem.pm 2010-07-21 16:00:58 +0000
@@ -132,6 +132,7 @@
'runtests.pl' => { perms => $owner_executable },
'testserver.pl' => { perms => $ws_executable },
'whine.pl' => { perms => $ws_executable },
+ 'tr_importxml.pl' => { perms => $ws_executable },
'customfield.pl' => { perms => $owner_executable },
'email_in.pl' => { perms => $ws_executable },
'sanitycheck.pl' => { perms => $ws_executable },
=== modified file 'Bugzilla/Search.pm'
--- Bugzilla/Search.pm 2010-06-24 17:07:37 +0000
+++ Bugzilla/Search.pm 2010-07-21 16:00:58 +0000
@@ -274,6 +274,12 @@
push(@supptables, "LEFT JOIN longdescs AS ldtime " .
"ON ldtime.bug_id = bugs.bug_id");
}
+ ### Testopia ###
+ if (grep($_ eq 'test_cases', @fields)){
+ push(@supptables, "LEFT JOIN test_case_bugs AS tcb " .
+ "ON bugs.bug_id = tcb.bug_id ");
+ }
+ ### end Testopia ###
if (grep($_ eq 'flagtypes.name', @fields)) {
push(@supptables, "LEFT JOIN flags ON flags.bug_id = bugs.bug_id AND attach_id IS NULL");
=== modified file 'Bugzilla/User.pm'
--- Bugzilla/User.pm 2010-02-18 00:16:31 +0000
+++ Bugzilla/User.pm 2010-07-21 16:00:58 +0000
@@ -361,6 +361,16 @@
return $self->{queries_available};
}
@ -45,7 +115,7 @@ diff -u -r1.178.2.3 User.pm
sub settings {
my ($self) = @_;
@@ -657,7 +667,7 @@
@@ -688,16 +698,23 @@
my $class_restricted = Bugzilla->params->{'useclassification'} && $class_id;
if (!defined $self->{selectable_products}) {
@ -53,17 +123,15 @@ diff -u -r1.178.2.3 User.pm
+ my $query = "(SELECT id, name AS pname " .
" FROM products " .
"LEFT JOIN group_control_map " .
" ON group_control_map.product_id = products.id ";
@@ -667,10 +677,17 @@
$query .= " AND group_control_map.membercontrol = " . CONTROLMAPMANDATORY;
}
$query .= " AND group_id NOT IN(" . $self->groups_as_string . ") " .
"ON group_control_map.product_id = products.id " .
" AND group_control_map.membercontrol = " . CONTROLMAPMANDATORY .
" AND group_id NOT IN(" . $self->groups_as_string . ") " .
- " WHERE group_id IS NULL " .
- "ORDER BY name";
-
- my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query);
+ " WHERE group_id IS NULL) " ;
+
- my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query);
+ $query .= "UNION (SELECT id, tr_products.name AS pname FROM products AS tr_products ".
+ "INNER JOIN test_plans ON tr_products.id = test_plans.product_id ".
+ "INNER JOIN test_plan_permissions ON test_plan_permissions.plan_id = test_plans.plan_id ".
@ -72,10 +140,11 @@ diff -u -r1.178.2.3 User.pm
+ $query .= "ORDER BY pname ";
+
+ my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query,undef,$self->id);
+
$self->{selectable_products} = Bugzilla::Product->new_from_list($prod_ids);
}
@@ -948,6 +965,33 @@
@@ -990,6 +1007,33 @@
$group_delete->execute($id, $group, GRANT_REGEXP) if $present;
}
}
@ -109,175 +178,82 @@ diff -u -r1.178.2.3 User.pm
}
sub product_responsibilities {
Index: Bugzilla/Search.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Search.pm,v
retrieving revision 1.173.2.1
diff -u -r1.173.2.1 Search.pm
--- Bugzilla/Search.pm 7 Jul 2009 18:20:08 -0000 1.173.2.1
+++ Bugzilla/Search.pm 4 Feb 2010 22:33:58 -0000
@@ -269,6 +269,12 @@
push(@supptables, "LEFT JOIN longdescs AS ldtime " .
"ON ldtime.bug_id = bugs.bug_id");
=== modified file 'Bugzilla/WebService/Server/XMLRPC.pm'
--- Bugzilla/WebService/Server/XMLRPC.pm 2010-03-10 20:53:01 +0000
+++ Bugzilla/WebService/Server/XMLRPC.pm 2010-07-21 16:00:58 +0000
@@ -78,7 +78,10 @@
$som->{_bz_do_taint} = 1;
}
+ ### Testopia ###
+ if (grep($_ eq 'test_cases', @fields)){
+ push(@supptables, "LEFT JOIN test_case_bugs AS tcb " .
+ "ON bugs.bug_id = tcb.bug_id ");
+ }
+ ### end Testopia ###
bless $som, 'Bugzilla::XMLRPC::SOM';
- Bugzilla->input_params($som->paramsin || {});
+ my $params = $som->paramsin;
+ # This allows positional parameters for Testopia.
+ $params = {} if ref $params ne 'HASH';
+ Bugzilla->input_params($params);
return $som;
}
my $minvotes;
if (defined $params->param('votes')) {
Index: Bugzilla/Error.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Error.pm,v
retrieving revision 1.24
diff -u -r1.24 Error.pm
--- Bugzilla/Error.pm 27 May 2008 22:08:59 -0000 1.24
+++ Bugzilla/Error.pm 4 Feb 2010 22:33:58 -0000
@@ -32,6 +32,7 @@
use Bugzilla::WebService::Constants;
use Bugzilla::Util;
use Date::Format;
+use JSON;
@@ -149,13 +152,15 @@
# We cannot use $^S to detect if we are in an eval(), because mod_perl
# already eval'uates everything, so $^S = 1 in all cases under mod_perl!
@@ -114,6 +115,16 @@
}
die SOAP::Fault->faultcode($code)->faultstring($message);
}
+ elsif (Bugzilla->error_mode == ERROR_MODE_AJAX) {
+ # JSON can't handle strings across lines.
+ $message =~ s/\n/ /gm;
+ my $err;
+ $err->{'success'} = JSON::false;
+ $err->{'error'} = $error;
+ $err->{'message'} = $message;
+ my $json = new JSON;
+ print $json->encode($err);
sub paramsin {
my $self = shift;
- return $self->{bz_params_in} if $self->{bz_params_in};
- my $params = $self->SUPER::paramsin(@_);
- if ($self->{_bz_do_taint}) {
- taint_data($params);
+ if (!$self->{bz_params_in}) {
+ my @params = $self->SUPER::paramsin(@_);
+ if ($self->{_bz_do_taint}) {
+ taint_data(@params);
+ }
+ $self->{bz_params_in} = \@params;
}
exit;
}
Index: Bugzilla/Bug.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Bug.pm,v
retrieving revision 1.276.2.14
diff -u -r1.276.2.14 Bug.pm
--- Bugzilla/Bug.pm 1 Feb 2010 00:21:45 -0000 1.276.2.14
+++ Bugzilla/Bug.pm 4 Feb 2010 22:33:58 -0000
@@ -2914,6 +2914,14 @@
"SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias);
- $self->{bz_params_in} = $params;
- return $self->{bz_params_in};
+ my $params = $self->{bz_params_in};
+ return wantarray ? @$params : $params->[0];
}
+sub get_test_case_count {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ my $row_count = $dbh->selectall_arrayref(
+ "SELECT DISTINCT case_id FROM test_case_bugs WHERE bug_id = ?",
+ undef, $self->bug_id);
+ return scalar @$row_count;
+}
#####################################################################
# Subroutines
#####################################################################
Index: template/en/default/admin/products/confirm-delete.html.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/admin/products/confirm-delete.html.tmpl,v
retrieving revision 1.11
diff -u -r1.11 confirm-delete.html.tmpl
--- template/en/default/admin/products/confirm-delete.html.tmpl 18 Dec 2008 17:18:20 -0000 1.11
+++ template/en/default/admin/products/confirm-delete.html.tmpl 4 Feb 2010 22:33:58 -0000
@@ -243,6 +243,8 @@
[% Hook.process("confirmation") %]
+[% Hook.process("additional-product-values") %]
+
[% IF product.bug_count == 0 || Param('allowbugdeletion') %]
<p>Do you really want to delete this product?</p>
Index: Bugzilla/WebService/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/WebService/User.pm,v
retrieving revision 1.14
diff -u -r1.14 User.pm
--- Bugzilla/WebService/User.pm 26 Jan 2009 20:40:22 -0000 1.14
+++ Bugzilla/WebService/User.pm 4 Feb 2010 22:33:58 -0000
@@ -223,6 +223,32 @@
return { users => \@users };
}
+#################
+# User Lookup #
+#################
+
+sub lookup_login_by_id {
+ my $self = shift;
+ my ($author_id) = @_;
+
+ my $user = new Bugzilla::User($author_id);
+
+ my $result = defined $user ? $user->login : '';
+
+ # Result is user login string or empty string if failed
+ return $result;
+}
+
+sub lookup_id_by_login {
+ my $self = shift;
+ my ($author) = @_;
+
+ my $result = Bugzilla::User::login_to_id($author);
+
+ # Result is user id or 0 if failed
+ return $result;
+}
+
1;
=== modified file 'Bugzilla/WebService/Util.pm'
--- Bugzilla/WebService/Util.pm 2009-11-09 18:27:52 +0000
+++ Bugzilla/WebService/Util.pm 2010-07-21 16:00:58 +0000
@@ -52,13 +52,13 @@
}
__END__
Index: Bugzilla/DB/Mysql.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/DB/Mysql.pm,v
retrieving revision 1.72.2.5
diff -u -r1.72.2.5 Mysql.pm
--- Bugzilla/DB/Mysql.pm 31 Jan 2010 23:38:36 -0000 1.72.2.5
+++ Bugzilla/DB/Mysql.pm 4 Feb 2010 22:33:58 -0000
@@ -746,6 +746,9 @@
$self->bz_drop_index('bugs_fulltext', $index);
}
}
+ if ($table eq 'test_runs' && $name eq 'summary') {
+ $self->bz_drop_index('test_runs', 'test_runs_summary_idx');
+ }
sub taint_data {
- my $params = shift;
- return if !$params;
+ my @params = @_;
+ return if !@params;
# Though this is a private function, it hasn't changed since 2004 and
# should be safe to use, and prevents us from having to write it ourselves
# or require another module to do it.
- Test::Taint::_deeply_traverse(\&_delete_bad_keys, $params);
- Test::Taint::taint_deeply($params);
+ Test::Taint::_deeply_traverse(\&_delete_bad_keys, \@params);
+ Test::Taint::taint_deeply(\@params);
}
my $dropped = $self->bz_drop_related_fks($table, $name);
push(@dropped_fks, @$dropped);
Index: Bugzilla/Install/Filesystem.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Install/Filesystem.pm,v
retrieving revision 1.34.2.4
diff -u -r1.34.2.4 Filesystem.pm
--- Bugzilla/Install/Filesystem.pm 1 Feb 2010 00:50:15 -0000 1.34.2.4
+++ Bugzilla/Install/Filesystem.pm 4 Feb 2010 22:33:58 -0000
@@ -119,6 +119,7 @@
'runtests.pl' => { perms => $owner_executable },
'testserver.pl' => { perms => $ws_executable },
'whine.pl' => { perms => $ws_executable },
+ 'tr_importxml.pl' => { perms => $ws_executable },
'customfield.pl' => { perms => $owner_executable },
'email_in.pl' => { perms => $ws_executable },
'sanitycheck.pl' => { perms => $ws_executable },
Index: template/en/default/global/setting-descs.none.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/global/setting-descs.none.tmpl,v
retrieving revision 1.15.2.1
diff -u -r1.15.2.1 setting-descs.none.tmpl
--- template/en/default/global/setting-descs.none.tmpl 19 Aug 2009 21:41:45 -0000 1.15.2.1
+++ template/en/default/global/setting-descs.none.tmpl 4 Feb 2010 22:33:58 -0000
sub _delete_bad_keys {
@@ -79,6 +79,11 @@
sub validate {
my ($self, $params, @keys) = @_;
+
+ # If $params is defined but not a reference, then we weren't
+ # sent any parameters at all, and we're getting @keys where
+ # $params should be.
+ return ($self, undef) if (defined $params and !ref $params);
# If @keys is not empty then we convert any named
# parameters that have scalar values to arrayrefs
=== modified file 'template/en/default/global/setting-descs.none.tmpl'
--- template/en/default/global/setting-descs.none.tmpl 2009-08-19 21:40:07 +0000
+++ template/en/default/global/setting-descs.none.tmpl 2010-07-21 16:00:58 +0000
@@ -40,6 +40,7 @@
"never" => "Never",
"cc_unless_role" => "Only if I have no role on them",

View File

@ -1,34 +1,104 @@
Index: Bugzilla/Constants.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Constants.pm,v
retrieving revision 1.109.2.13
diff -u -r1.109.2.13 Constants.pm
--- Bugzilla/Constants.pm 19 Nov 2009 02:13:50 -0000 1.109.2.13
+++ Bugzilla/Constants.pm 1 Dec 2009 23:50:42 -0000
@@ -134,6 +134,7 @@
=== modified file 'Bugzilla/Bug.pm'
--- Bugzilla/Bug.pm 2010-05-14 12:25:20 +0000
+++ Bugzilla/Bug.pm 2010-07-21 16:12:01 +0000
@@ -3046,6 +3046,14 @@
"SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias);
}
+sub get_test_case_count {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ my $row_count = $dbh->selectall_arrayref(
+ "SELECT DISTINCT case_id FROM test_case_bugs WHERE bug_id = ?",
+ undef, $self->bug_id);
+ return scalar @$row_count;
+}
#####################################################################
# Subroutines
#####################################################################
=== modified file 'Bugzilla/Constants.pm'
--- Bugzilla/Constants.pm 2010-06-24 23:14:56 +0000
+++ Bugzilla/Constants.pm 2010-07-21 16:12:01 +0000
@@ -140,6 +140,7 @@
ERROR_MODE_WEBPAGE
ERROR_MODE_DIE
ERROR_MODE_DIE_SOAP_FAULT
+ ERROR_MODE_AJAX
ERROR_MODE_JSON_RPC
INSTALLATION_MODE_INTERACTIVE
INSTALLATION_MODE_NON_INTERACTIVE
@@ -386,6 +387,7 @@
@@ -421,6 +422,7 @@
use constant ERROR_MODE_WEBPAGE => 0;
use constant ERROR_MODE_DIE => 1;
use constant ERROR_MODE_DIE_SOAP_FAULT => 2;
+use constant ERROR_MODE_AJAX => 3;
+use constant ERROR_MODE_AJAX => 4;
use constant ERROR_MODE_JSON_RPC => 3;
# The various modes that checksetup.pl can run in.
use constant INSTALLATION_MODE_INTERACTIVE => 0;
Index: Bugzilla/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/User.pm,v
retrieving revision 1.178.2.3
diff -u -r1.178.2.3 User.pm
--- Bugzilla/User.pm 2 Jun 2009 22:04:13 -0000 1.178.2.3
+++ Bugzilla/User.pm 1 Dec 2009 23:50:43 -0000
@@ -339,6 +339,16 @@
=== modified file 'Bugzilla/Error.pm'
--- Bugzilla/Error.pm 2010-04-01 01:06:03 +0000
+++ Bugzilla/Error.pm 2010-07-21 16:12:01 +0000
@@ -32,6 +32,7 @@
use Bugzilla::WebService::Constants;
use Bugzilla::Util;
use Date::Format;
+use JSON;
# We cannot use $^S to detect if we are in an eval(), because mod_perl
# already eval'uates everything, so $^S = 1 in all cases under mod_perl!
@@ -135,6 +136,16 @@
$server->response($server->error_response_header);
}
}
+ elsif (Bugzilla->error_mode == ERROR_MODE_AJAX) {
+ # JSON can't handle strings across lines.
+ $message =~ s/\n/ /gm;
+ my $err;
+ $err->{'success'} = JSON::false;
+ $err->{'error'} = $error;
+ $err->{'message'} = $message;
+ my $json = new JSON;
+ print $json->encode($err);
+ }
}
exit;
}
=== modified file 'Bugzilla/Install/Filesystem.pm'
--- Bugzilla/Install/Filesystem.pm 2010-07-13 23:03:47 +0000
+++ Bugzilla/Install/Filesystem.pm 2010-07-21 16:12:01 +0000
@@ -132,6 +132,7 @@
'runtests.pl' => { perms => $owner_executable },
'testserver.pl' => { perms => $ws_executable },
'whine.pl' => { perms => $ws_executable },
+ 'tr_importxml.pl' => { perms => $ws_executable },
'customfield.pl' => { perms => $owner_executable },
'email_in.pl' => { perms => $ws_executable },
'sanitycheck.pl' => { perms => $ws_executable },
=== modified file 'Bugzilla/Search.pm'
--- Bugzilla/Search.pm 2010-07-05 23:39:24 +0000
+++ Bugzilla/Search.pm 2010-07-21 16:12:01 +0000
@@ -274,6 +274,12 @@
push(@supptables, "LEFT JOIN longdescs AS ldtime " .
"ON ldtime.bug_id = bugs.bug_id");
}
+ ### Testopia ###
+ if (grep($_ eq 'test_cases', @fields)){
+ push(@supptables, "LEFT JOIN test_case_bugs AS tcb " .
+ "ON bugs.bug_id = tcb.bug_id ");
+ }
+ ### end Testopia ###
if (grep($_ eq 'flagtypes.name', @fields)) {
push(@supptables, "LEFT JOIN flags ON flags.bug_id = bugs.bug_id AND attach_id IS NULL");
=== modified file 'Bugzilla/User.pm'
--- Bugzilla/User.pm 2010-02-18 00:16:31 +0000
+++ Bugzilla/User.pm 2010-07-21 16:12:01 +0000
@@ -361,6 +361,16 @@
return $self->{queries_available};
}
@ -45,7 +115,7 @@ diff -u -r1.178.2.3 User.pm
sub settings {
my ($self) = @_;
@@ -657,7 +667,7 @@
@@ -688,16 +698,23 @@
my $class_restricted = Bugzilla->params->{'useclassification'} && $class_id;
if (!defined $self->{selectable_products}) {
@ -53,17 +123,15 @@ diff -u -r1.178.2.3 User.pm
+ my $query = "(SELECT id, name AS pname " .
" FROM products " .
"LEFT JOIN group_control_map " .
" ON group_control_map.product_id = products.id ";
@@ -667,10 +677,17 @@
$query .= " AND group_control_map.membercontrol = " . CONTROLMAPMANDATORY;
}
$query .= " AND group_id NOT IN(" . $self->groups_as_string . ") " .
"ON group_control_map.product_id = products.id " .
" AND group_control_map.membercontrol = " . CONTROLMAPMANDATORY .
" AND group_id NOT IN(" . $self->groups_as_string . ") " .
- " WHERE group_id IS NULL " .
- "ORDER BY name";
-
- my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query);
+ " WHERE group_id IS NULL) " ;
+
- my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query);
+ $query .= "UNION (SELECT id, tr_products.name AS pname FROM products AS tr_products ".
+ "INNER JOIN test_plans ON tr_products.id = test_plans.product_id ".
+ "INNER JOIN test_plan_permissions ON test_plan_permissions.plan_id = test_plans.plan_id ".
@ -72,10 +140,11 @@ diff -u -r1.178.2.3 User.pm
+ $query .= "ORDER BY pname ";
+
+ my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query,undef,$self->id);
+
$self->{selectable_products} = Bugzilla::Product->new_from_list($prod_ids);
}
@@ -948,6 +965,33 @@
@@ -990,6 +1007,33 @@
$group_delete->execute($id, $group, GRANT_REGEXP) if $present;
}
}
@ -109,175 +178,10 @@ diff -u -r1.178.2.3 User.pm
}
sub product_responsibilities {
Index: Bugzilla/Error.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Error.pm,v
retrieving revision 1.24
diff -u -r1.24 Error.pm
--- Bugzilla/Error.pm 27 May 2008 22:08:59 -0000 1.24
+++ Bugzilla/Error.pm 1 Dec 2009 23:50:42 -0000
@@ -32,6 +32,7 @@
use Bugzilla::WebService::Constants;
use Bugzilla::Util;
use Date::Format;
+use JSON;
# We cannot use $^S to detect if we are in an eval(), because mod_perl
# already eval'uates everything, so $^S = 1 in all cases under mod_perl!
@@ -114,6 +115,16 @@
}
die SOAP::Fault->faultcode($code)->faultstring($message);
}
+ elsif (Bugzilla->error_mode == ERROR_MODE_AJAX) {
+ # JSON can't handle strings across lines.
+ $message =~ s/\n/ /gm;
+ my $err;
+ $err->{'success'} = JSON::false;
+ $err->{'error'} = $error;
+ $err->{'message'} = $message;
+ my $json = new JSON;
+ print $json->encode($err);
+ }
}
exit;
}
Index: Bugzilla/Search.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Search.pm,v
retrieving revision 1.173.2.1
diff -u -r1.173.2.1 Search.pm
--- Bugzilla/Search.pm 7 Jul 2009 18:20:08 -0000 1.173.2.1
+++ Bugzilla/Search.pm 1 Dec 2009 23:50:42 -0000
@@ -269,6 +269,12 @@
push(@supptables, "LEFT JOIN longdescs AS ldtime " .
"ON ldtime.bug_id = bugs.bug_id");
}
+ ### Testopia ###
+ if (grep($_ eq 'test_cases', @fields)){
+ push(@supptables, "LEFT JOIN test_case_bugs AS tcb " .
+ "ON bugs.bug_id = tcb.bug_id ");
+ }
+ ### end Testopia ###
my $minvotes;
if (defined $params->param('votes')) {
Index: Bugzilla/Bug.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Bug.pm,v
retrieving revision 1.276.2.13
diff -u -r1.276.2.13 Bug.pm
--- Bugzilla/Bug.pm 18 Nov 2009 06:31:59 -0000 1.276.2.13
+++ Bugzilla/Bug.pm 1 Dec 2009 23:50:42 -0000
@@ -2941,6 +2941,14 @@
"SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias);
}
+sub get_test_case_count {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ my $row_count = $dbh->selectall_arrayref(
+ "SELECT DISTINCT case_id FROM test_case_bugs WHERE bug_id = ?",
+ undef, $self->bug_id);
+ return scalar @$row_count;
+}
#####################################################################
# Subroutines
#####################################################################
Index: template/en/default/admin/products/confirm-delete.html.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/admin/products/confirm-delete.html.tmpl,v
retrieving revision 1.11
diff -u -r1.11 confirm-delete.html.tmpl
--- template/en/default/admin/products/confirm-delete.html.tmpl 18 Dec 2008 17:18:20 -0000 1.11
+++ template/en/default/admin/products/confirm-delete.html.tmpl 1 Dec 2009 23:50:43 -0000
@@ -243,6 +243,8 @@
[% Hook.process("confirmation") %]
+[% Hook.process("additional-product-values") %]
+
[% IF product.bug_count == 0 || Param('allowbugdeletion') %]
<p>Do you really want to delete this product?</p>
Index: Bugzilla/WebService/User.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/WebService/User.pm,v
retrieving revision 1.14
diff -u -r1.14 User.pm
--- Bugzilla/WebService/User.pm 26 Jan 2009 20:40:22 -0000 1.14
+++ Bugzilla/WebService/User.pm 1 Dec 2009 23:50:43 -0000
@@ -223,6 +223,32 @@
return { users => \@users };
}
+#################
+# User Lookup #
+#################
+
+sub lookup_login_by_id {
+ my $self = shift;
+ my ($author_id) = @_;
+
+ my $user = new Bugzilla::User($author_id);
+
+ my $result = defined $user ? $user->login : '';
+
+ # Result is user login string or empty string if failed
+ return $result;
+}
+
+sub lookup_id_by_login {
+ my $self = shift;
+ my ($author) = @_;
+
+ my $result = Bugzilla::User::login_to_id($author);
+
+ # Result is user id or 0 if failed
+ return $result;
+}
+
1;
__END__
Index: Bugzilla/DB/Mysql.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/DB/Mysql.pm,v
retrieving revision 1.72.2.3
diff -u -r1.72.2.3 Mysql.pm
--- Bugzilla/DB/Mysql.pm 20 Sep 2009 22:33:59 -0000 1.72.2.3
+++ Bugzilla/DB/Mysql.pm 1 Dec 2009 23:50:43 -0000
@@ -746,6 +746,9 @@
$self->bz_drop_index('bugs_fulltext', $index);
}
}
+ if ($table eq 'test_runs' && $name eq 'summary') {
+ $self->bz_drop_index('test_runs', 'test_runs_summary_idx');
+ }
my $dropped = $self->bz_drop_related_fks($table, $name);
push(@dropped_fks, @$dropped);
Index: Bugzilla/Install/Filesystem.pm
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/Bugzilla/Install/Filesystem.pm,v
retrieving revision 1.34
diff -u -r1.34 Filesystem.pm
--- Bugzilla/Install/Filesystem.pm 23 Jan 2009 21:34:42 -0000 1.34
+++ Bugzilla/Install/Filesystem.pm 1 Dec 2009 23:50:43 -0000
@@ -112,6 +112,7 @@
'runtests.pl' => { perms => $owner_executable },
'testserver.pl' => { perms => $ws_executable },
'whine.pl' => { perms => $ws_executable },
+ 'tr_importxml.pl' => { perms => $ws_executable },
'customfield.pl' => { perms => $owner_executable },
'email_in.pl' => { perms => $ws_executable },
'sanitycheck.pl' => { perms => $ws_executable },
Index: template/en/default/global/setting-descs.none.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/global/setting-descs.none.tmpl,v
retrieving revision 1.15.2.1
diff -u -r1.15.2.1 setting-descs.none.tmpl
--- template/en/default/global/setting-descs.none.tmpl 19 Aug 2009 21:41:45 -0000 1.15.2.1
+++ template/en/default/global/setting-descs.none.tmpl 1 Dec 2009 23:50:43 -0000
=== modified file 'template/en/default/global/setting-descs.none.tmpl'
--- template/en/default/global/setting-descs.none.tmpl 2009-08-19 21:40:07 +0000
+++ template/en/default/global/setting-descs.none.tmpl 2010-07-21 16:12:07 +0000
@@ -40,6 +40,7 @@
"never" => "Never",
"cc_unless_role" => "Only if I have no role on them",
@ -286,3 +190,4 @@ diff -u -r1.15.2.1 setting-descs.none.tmpl
"quote_replies" => "Quote the associated comment when you click on its reply link",
"quoted_reply" => "Quote the full comment",
"simple_reply" => "Reference the comment number only",

File diff suppressed because one or more lines are too long

View File

@ -3,7 +3,7 @@
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/strings.js
* START OF FILE - /testopia/extensions/Testopia/js/strings.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -36,11 +36,11 @@ ENVIRONMENT_DELETE_WARNING = 'You are about to delete the selected test environm
PRODUCT_PLAN_IMPORT = 'Accepts XML files under 2 MB in size. <br> See <a href="extensions/Testopia/testopia.xsd" target="_blank">testopia.xsd</a> for proper format.';
PLAN_CASES_IMPORT = 'Accepts CSV and XML files under 2 MB in size. <br> See <a href="extensions/Testopia/import_example.csv" target="_blank">import_example.csv</a> and <a href="extensions/Testopia/testopia.xsd" target="_blank">testopia.xsd</a> for proper format.';
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/strings.js
* END OF FILE - /testopia/extensions/Testopia/js/strings.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/vars.js
* START OF FILE - /testopia/extensions/Testopia/js/vars.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -172,11 +172,11 @@ var imgButtonTpl = new Ext.Template(
'</tr></tbody></table>');
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/vars.js
* END OF FILE - /testopia/extensions/Testopia/js/vars.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/util.js
* START OF FILE - /testopia/extensions/Testopia/js/util.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -1034,11 +1034,11 @@ Testopia.Util.DisableTools = function(tbar, ex){
}
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/util.js
* END OF FILE - /testopia/extensions/Testopia/js/util.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/attachments.js
* START OF FILE - /testopia/extensions/Testopia/js/attachments.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -1481,11 +1481,11 @@ Testopia.Attachment.NewAttachmentPopup = function(object){
};
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/attachments.js
* END OF FILE - /testopia/extensions/Testopia/js/attachments.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/plan.js
* START OF FILE - /testopia/extensions/Testopia/js/plan.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -2558,6 +2558,15 @@ Testopia.TestPlan.ClonePanel = function(plan){
id: 'copy_runs',
title: 'Copy Test Runs',
collapsed: true,
listeners: {
'expand': function(){
Ext.getCmp('plan_clone_build_chooser').allowBlank = false;
Ext.getCmp('plan_clone_environment_chooser').allowBlank = false;
},
'collapse':function(){
Ext.getCmp('plan_clone_build_chooser').allowBlank = true;
Ext.getCmp('plan_clone_environment_chooser').allowBlank = true;
}},
items: [{
xtype: 'checkbox',
name: 'keep_run_managers',
@ -2613,11 +2622,11 @@ Testopia.TestPlan.ClonePopup = function(plan){
};
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/plan.js
* END OF FILE - /testopia/extensions/Testopia/js/plan.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/case.js
* START OF FILE - /testopia/extensions/Testopia/js/case.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -4385,11 +4394,11 @@ Testopia.TestCase.clonePopup = function(product_id, cases){
};
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/case.js
* END OF FILE - /testopia/extensions/Testopia/js/case.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/caserun.js
* START OF FILE - /testopia/extensions/Testopia/js/caserun.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -6918,7 +6927,7 @@ Testopia.TestCaseRun.Info = function(){
loadingText: 'Loading...',
tpl: new Ext.XTemplate('<tpl for=".">', '<div id="notesdiv" style="margin: 5px; padding: 5px; border: 1px solid black;"><pre>{notes}</pre></div>', '</tpl>', '<div class="x-clear"><input id="caserun_append_note_fld" ></div>')
}],
bbar: ['Add a Note: ', {
tbar: ['Add a Note: ', {
xtype: 'textfield',
id: 'caserun_append_note_fld',
listeners: {'afterrender': function(){
@ -6944,11 +6953,11 @@ Ext.extend(Testopia.TestCaseRun.Info, Ext.Panel, this);
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/caserun.js
* END OF FILE - /testopia/extensions/Testopia/js/caserun.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/run.js
* START OF FILE - /testopia/extensions/Testopia/js/run.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -8640,11 +8649,11 @@ Ext.extend(Testopia.TestRun.ProgressBar, Ext.ProgressBar, {
});
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/run.js
* END OF FILE - /testopia/extensions/Testopia/js/run.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/build.js
* START OF FILE - /testopia/extensions/Testopia/js/build.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -8951,11 +8960,11 @@ Ext.extend(Testopia.Build.Grid, Ext.grid.GridPanel, {
});
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/build.js
* END OF FILE - /testopia/extensions/Testopia/js/build.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/category.js
* START OF FILE - /testopia/extensions/Testopia/js/category.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -9242,11 +9251,11 @@ Testopia.Category.remove = function(){
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/category.js
* END OF FILE - /testopia/extensions/Testopia/js/category.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/diff-tabs.js
* START OF FILE - /testopia/extensions/Testopia/js/diff-tabs.js
*/
Ext.ux.TabCloseMenu = function(){
var tabs, menu, ctxItem;
@ -9374,11 +9383,11 @@ Ext.extend(diff_tab_panel, Ext.TabPanel);
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/diff-tabs.js
* END OF FILE - /testopia/extensions/Testopia/js/diff-tabs.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/environment.js
* START OF FILE - /testopia/extensions/Testopia/js/environment.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -9797,11 +9806,11 @@ Ext.extend(Testopia.Environment.Grid, Ext.grid.EditorGridPanel, {
});
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/environment.js
* END OF FILE - /testopia/extensions/Testopia/js/environment.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/product.js
* START OF FILE - /testopia/extensions/Testopia/js/product.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -9967,11 +9976,11 @@ Testopia.Product.MilestoneCombo = function(cfg){
Ext.extend(Testopia.Product.MilestoneCombo, Ext.form.ComboBox);
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/product.js
* END OF FILE - /testopia/extensions/Testopia/js/product.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/search.js
* START OF FILE - /testopia/extensions/Testopia/js/search.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -10964,11 +10973,11 @@ Testopia.Search.LinkPopup = function(params){
};
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/search.js
* END OF FILE - /testopia/extensions/Testopia/js/search.js
*/
/*
* START OF FILE - /bmo-3.6/extensions/Testopia/js/tags.js
* START OF FILE - /testopia/extensions/Testopia/js/tags.js
*/
/*
* The contents of this file are subject to the Mozilla Public
@ -11430,7 +11439,7 @@ Testopia.Tags.update = function(type, grid){
};
/*
* END OF FILE - /bmo-3.6/extensions/Testopia/js/tags.js
* END OF FILE - /testopia/extensions/Testopia/js/tags.js
*/
/*

File diff suppressed because one or more lines are too long

View File

@ -21,9 +21,11 @@
# Jeff Dayley <jedayley@novell.com>
use strict;
use lib 't';
use lib '.';
use lib '../..';
use lib qw(. t ../..) ;
use Bugzilla;
BEGIN {Bugzilla->extensions}
use Test::Unit::Debug qw(debug_pkgs);
use Test::Unit::TestRunner;

View File

@ -172,7 +172,7 @@ else {
$bug = Bugzilla::Bug->new($cgi->param('bug'),Bugzilla->user->id);
my $bug_id = $bug->bug_id;
my $description = '<br><pre>' . wrap_comment(@{Bugzilla::Bug::GetComments($bug_id,'oldest_to_newest')}[0]->{'body'}) . '</pre>';
my $description = '<br><pre>' . wrap_comment(@{$bug->comments({order => 'oldest_to_newest'})}[0]->{'thetext'}) . '</pre>';
my $short_desc = $bug->short_desc;
$summary = Bugzilla->params->{"bug-to-test-case-summary"};
@ -183,11 +183,10 @@ else {
$vars->{'bugs'} = $bug->bug_id;
}
my $case = Bugzilla::Extension::Testopia::TestCase->new(
{'plans' => join(',', @plan_ids),
'category' => {name => '--default--'},
'summary' => $summary,
});
my $case = {'plans' => join(',', @plan_ids),
'category' => {name => '--default--'},
'summary' => $summary,
};
$vars->{'tc'} = $case;
$vars->{'product_id'} = $plans[0]->product_id;

View File

@ -327,12 +327,18 @@ else{
else{
detaint_natural($prod_id);
my $prod = $plan->lookup_product($prod_id);
unless (Bugzilla->user->can_see_product($prod)){
if ($prod && !Bugzilla->user->can_see_product($prod)){
print '{ERROR:"You do not have permission to view this product"}';
exit;
}
my $product = Bugzilla::Extension::Testopia::Product->new($prod_id);
@versions = @{$product->versions};
if ($prod){
my $product = Bugzilla::Extension::Testopia::Product->new($prod_id);
@versions = @{$product->versions};
}
else {
@versions = [];
}
}
my $json = new JSON;
@ -472,7 +478,7 @@ else{
my $tcaction = Bugzilla->params->{"bug-to-test-case-action"};
my $bug_id = $bug->bug_id;
my $description = '<br><pre>' . wrap_comment(@{Bugzilla::Bug::GetComments($bug_id,'oldest_to_newest')}[0]->{'body'}) . '</pre>';
my $description = '<br><pre>' . wrap_comment(@{$bug->comments({order => 'oldest_to_newest'})}[0]->{'thetext'}) . '</pre>';
$tcaction =~ s/%id%/<a href="show_bug.cgi?id=$bug_id">$bug_id<\/a>/g;
$tcaction =~ s/%description%/$description/g;

View File

@ -1,47 +0,0 @@
#!/usr/bin/perl -wT
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# Contributor(s): Marc Schumann <wurblzap@gmail.com>
use strict;
use lib qw(. lib);
use Bugzilla;
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::WebService::Constants;
# Use an eval here so that runtests.pl accepts this script even if SOAP-Lite
# is not installed.
eval { require Bugzilla::WebService::Server::XMLRPC; };
$@ && ThrowCodeError('soap_not_installed');
Bugzilla->usage_mode(USAGE_MODE_WEBSERVICE);
# Fix the error code that SOAP::Lite uses for Perl errors.
local $SOAP::Constants::FAULT_SERVER;
$SOAP::Constants::FAULT_SERVER = ERROR_UNKNOWN_FATAL;
# The line above is used, this one is ignored, but SOAP::Lite
# might start using this constant (the correct one) for XML-RPC someday.
local $XMLRPC::Constants::FAULT_SERVER;
$XMLRPC::Constants::FAULT_SERVER = ERROR_UNKNOWN_FATAL;
local @INC = (bz_locations()->{extensionsdir}, @INC);
my $server = new Bugzilla::WebService::Server::XMLRPC;
# We use a sub for on_action because that gets us the info about what
# class is being called. Note that this is a hack--this is technically
# for setting SOAPAction, which isn't used by XML-RPC.
$server->on_action(sub { $server->handle_login(WS_DISPATCH, @_) })
->handle();