Sync with 2431

This commit is contained in:
ghendricks%novell.com 2006-12-01 18:06:58 +00:00
parent 9032eff951
commit 3da3633ddb
43 changed files with 827 additions and 228 deletions

View File

@ -51,6 +51,37 @@ RELATIONSHIPS
);
#
# Fields to include when exporting a Test Case.
#
# All _id fields but case_id are converted to a string representation.
#
@Bugzilla::Testopia::Constants::TESTCASE_EXPORT = qw(
case_id
summary
set_up
break_down
action
expected_results
alias
arguments
author_id
blocks
case_status_id
category_id
components
creation_date
default_tester_id
depends_on
isautomated
plans
priority_id
requirement
script
tags
version
);
@Bugzilla::Constants::EXPORT_OK = qw(contenttypes);
# Test Case Status

View File

@ -50,8 +50,9 @@ sub builds {
my $ref = $dbh->selectcol_arrayref(
"SELECT build_id
FROM test_builds
WHERE product_id = ?",
FROM test_builds
WHERE product_id = ?
ORDER BY name",
undef, $self->{'id'});
my @objs;
foreach my $id (@{$ref}){
@ -68,7 +69,8 @@ sub categories {
my $ref = $dbh->selectcol_arrayref(
"SELECT category_id
FROM test_case_categories
WHERE product_id = ?",
WHERE product_id = ?
ORDER BY name",
undef, $self->{'id'});
my @objs;
foreach my $id (@{$ref}){

View File

@ -366,7 +366,7 @@ sub get_product_ids {
if ($self->id == 0){
my @ids;
foreach my $plan (@{$self->plans}){
push @ids, $plan->product_id if Bugzilla->user->can_see_product($plan->product_name);
push @ids, $plan->product_id if Bugzilla->user->can_see_product($plan->product->name);
}
return \@ids;
}
@ -1345,8 +1345,10 @@ sub candelete {
# Allow plan author to delete if this case is linked only to plans she owns.
my $own_all = 1;
foreach my $plan (@{$self->plans}){
$own_all = 0 if (Bugzilla->user->id != $plan->author->id);
last;
if (Bugzilla->user->id != $plan->author->id) {
$own_all = 0;
last;
}
}
return 1 if $own_all;
@ -1551,7 +1553,10 @@ sub components {
my @comps;
foreach my $id (@$comps){
push @comps, Bugzilla::Component->new($id);
my $comp = Bugzilla::Component->new($id);
my $prod = Bugzilla::Product->new($comp->product_id);
$comp->{'product_name'} = $prod->name;
push @comps, $comp;
}
$self->{'components'} = \@comps;
return $self->{'components'};

View File

@ -991,7 +991,7 @@ sub candelete {
=head2 obliterate
Removes this caserun, it's history, and all things that reference it.
Removes this caserun, its history, and all things that reference it.
=cut

View File

@ -51,6 +51,7 @@ use Bugzilla::Testopia::TestCase;
use Bugzilla::Testopia::Category;
use Bugzilla::Testopia::Build;
use Bugzilla::Testopia::TestTag;
use Bugzilla::Testopia::Product;
use Bugzilla::Bug;
#TODO: Add this to checksetup
@ -1002,34 +1003,6 @@ sub attachments {
}
=head2 builds
Returns a reference to a list of Testopia::Build objects associated
with this plan
=cut
sub builds {
my ($self) = @_;
my $dbh = Bugzilla->dbh;
return $self->{'builds'} if exists $self->{'builds'};
my $builds =
$dbh->selectcol_arrayref(
"SELECT build_id
FROM test_builds
WHERE product_id = ?",
undef, $self->{'product_id'});
my @builds;
foreach my $id (@{$builds}){
push @builds, Bugzilla::Testopia::Build->new($id);
}
$self->{'builds'} = \@builds;
return $self->{'builds'};
}
=head2 bugs
Returns a reference to a list of Bugzilla::Bug objects associated
@ -1057,51 +1030,19 @@ sub bugs {
return $self->{'bugs'};
}
=head2 product_name
=head2 product
Returns the name of the product this plan is associated with
Returns the product this plan is associated with
=cut
sub product_name {
sub product {
my ($self) = @_;
my $dbh = Bugzilla->dbh;
return $self->{'product_name'} if exists $self->{'product_name'};
$self->{'product_name'} = undef;
$self->{'product_name'} = $dbh->selectrow_array(
"SELECT name FROM products
WHERE id = ?",
undef, $self->{'product_id'});
return $self->{'product_name'};
}
=head2 categories
Returns a reference to a list of Testopia::Category objects
associated with this plan
=cut
sub categories {
my ($self) = @_;
my $dbh = Bugzilla->dbh;
return $self->{'categories'} if exists $self->{'categories'};
my $categories =
$dbh->selectcol_arrayref(
"SELECT category_id
FROM test_case_categories
WHERE product_id = ?",
undef, $self->{'product_id'});
my @categories;
foreach my $c (@{$categories}){
push @categories, Bugzilla::Testopia::Category->new($c);
}
$self->{'categories'} = \@categories;
return $self->{'categories'};
return $self->{'product'} if exists $self->{'product'};
$self->{'product'} = Bugzilla::Testopia::Product->new($self->product_id);
return $self->{'product'};
}
=head2 test_cases

View File

@ -88,19 +88,24 @@ sub add_tag()
push @{$self->tags}, $tag;
}
# Temporary copy of Bugzilla::Testopia::TestPlan->get_available_products(). Remove when bug 220134 is fixed.
sub TEMP_get_product_components {
my ($product_id) = @_;
=head2 get_available_products
Returns a list of products. This is the same code as Bugzilla::Testopia::TestPlan->get_available_products
without view restrictions.
=cut
sub get_available_products {
my $dbh = Bugzilla->dbh;
my $ref = $dbh->selectall_arrayref(
"SELECT DISTINCT id, name
FROM components
WHERE product_id IN($product_id)
ORDER BY name",
{'Slice'=>{}});
return $ref;
my $products = $dbh->selectall_arrayref(
"SELECT id, name
FROM products
ORDER BY name",
{"Slice"=>{}});
return $products;
}
sub add_component()
{
my ($self,$component,$component_product) = @_;
@ -110,7 +115,7 @@ sub add_component()
return "Component $component needs to provide a product." if ( $component_product eq "" );
# Find the product identifier.
my $products_ref = Bugzilla::Testopia::TestPlan->get_available_products();
my $products_ref = get_available_products();
foreach my $product (@$products_ref)
{
if ( $component_product eq $product->{name} )
@ -122,7 +127,7 @@ sub add_component()
return "Cannot find product $component_product for component $component." if ( $product_id eq "" );
# Find the component identifier for the product's componet
my $components_ref = TEMP_get_product_components($product_id);
my $components_ref = Bugzilla::Testopia::TestPlan->get_product_components($product_id,1);
foreach my $product_component ( @$components_ref )
{
if ( $component eq $product_component->{name} )
@ -305,7 +310,7 @@ sub store()
{
my $categoryid = -1;
push my @categories, @{$testplan->categories};
push my @categories, @{$testplan->product->categories};
foreach my $category (@categories)
{
if ( $category->name eq $self->category )

View File

@ -0,0 +1,98 @@
# -*- 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>
# Dallas Harken <dharken@novell.com>
package Bugzilla::WebService;
use strict;
use Bugzilla::Config;
use Bugzilla::WebService::Constants;
sub fail_unimplemented
{
my $this = shift;
die SOAP::Fault
->faultcode(ERROR_UNIMPLEMENTED)
->faultstring('Service Unimplemented');
}
sub login
{
my $self = shift;
# Check for use of iChain first
if (Param('user_verify_class') ne 'iChain')
{
#
# Check for use of Basic Authorization
#
# WARNING - Your must modify your Apache server's configuration
# to allow the HTTP_AUTHORIZATION env parameter to be passed through!
# This requires using the rewrite module.
#
if (defined($ENV{'HTTP_AUTHORIZATION'}))
{
if ($ENV{'HTTP_AUTHORIZATION'} =~ /^Basic +(.*)$/os)
{
# HTTP Basic Authentication
my($login, $password) = split(/:/, MIME::Base64::decode_base64($1), 2);
my $cgi = Bugzilla->cgi;
$cgi->param("Bugzilla_login", $login);
$cgi->param("Bugzilla_password", $password);
}
}
}
Bugzilla->login;
}
sub logout
{
my $self = shift;
Bugzilla->logout;
}
package Bugzilla::WebService::XMLRPC::Transport::HTTP::CGI;
use strict;
use Bugzilla::WebService::Constants;
eval 'use base qw(XMLRPC::Transport::HTTP::CGI)';
sub make_fault
{
my $self = shift;
# RPC Fault Code must be an integer
$self->SUPER::make_fault(ERROR_FAULT_SERVER, $_[1]);
}
sub make_response
{
my $self = shift;
$self->SUPER::make_response(@_);
# XMLRPC::Transport::HTTP::CGI doesn't know about Bugzilla carrying around
# its cookies in Bugzilla::CGI, so we need to copy them over.
foreach (@{Bugzilla->cgi->{'Bugzilla_cookie_list'}}) {
$self->response->headers->push_header('Set-Cookie', $_);
}
}
1;

View File

@ -31,13 +31,13 @@ sub lookup_name_by_id
die "Invalid Build ID"
unless defined $build_id && length($build_id) > 0 && $build_id > 0;
Bugzilla->login;
$self->login;
my $build = new Bugzilla::Testopia::Build($build_id);
my $result = defined $build ? $build->name : '';
Bugzilla->logout;
$self->logout;
# Result is build name string or empty string if failed
return $result;
@ -48,11 +48,11 @@ sub lookup_id_by_name
my $self = shift;
my ($name) = @_;
Bugzilla->login;
$self->login;
my $result = Bugzilla::Testopia::Build->check_build_by_name($name);
Bugzilla->logout;
$self->logout;
if (!defined $result)
{

View File

@ -0,0 +1,83 @@
# -*- 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>
# Dallas Harken <dharken@novell.com>
package Bugzilla::WebService::Testopia::Product;
use strict;
use base qw(Bugzilla::WebService);
use Bugzilla::Testopia::Product;
sub lookup_name_by_id
{
my $self = shift;
my ($product_id) = @_;
die "Invalid Product ID"
unless defined $product_id && length($product_id) > 0 && $product_id > 0;
$self->login;
my $product = new Bugzilla::Testopia::Product($product_id);
my $result = defined $product ? $product->name : '';
$self->logout;
# Result is product name string or empty string if failed
return $result;
}
sub lookup_id_by_name
{
my $self = shift;
my ($name) = @_;
$self->login;
my $result = Bugzilla::Testopia::Product->check_product_by_name($name);
$self->logout;
if (!defined $result)
{
$result = 0;
}
# Result is product id or 0 if failed
return $result;
}
#sub get_product
#{
# my $self = shift;
# my ($product_id) = @_;
#
# Bugzilla->login;
#
# # We can detaint immediately if what we get passed is fully numeric.
# # We leave bug alias checks to Bugzilla::Testopia::TestPlan::new.
#
# if ($product_id =~ /^[0-9]+$/) {
# detaint_natural($product_id);
# }
#
# return new Bugzilla::Product($product_id);
#}
1;

View File

@ -21,64 +21,12 @@ use strict;
use base qw(Bugzilla::WebService);
use Bugzilla::Util qw(detaint_natural);
use Bugzilla::Product;
use Bugzilla::Constants;
use Bugzilla::User;
use Bugzilla::Testopia::TestPlan;
use Bugzilla::Testopia::Search;
use Bugzilla::Testopia::Table;
# Convert string field values to their respective integer id's
sub _convert_to_ids
{
my ($hash) = @_;
if (defined($$hash{"author"}))
{
$$hash{"author_id"} = login_to_id($$hash{"author"});
}
delete $$hash{"author"};
if (defined($$hash{"product"}))
{
my $product = Bugzilla::Product::check_product($$hash{"product"});
$$hash{"product_id"} = $product->id;
}
delete $$hash{"product"};
if (defined($$hash{"type"}))
{
$$hash{"type_id"} = Bugzilla::Testopia::TestPlan::lookup_type_by_name($$hash{"type"});
}
delete $$hash{"type"};
}
# Convert fields with integer id's to their respective string values
sub _convert_to_strings
{
my ($hash) = @_;
$$hash{"author"} = "";
if (defined($$hash{"author_id"}))
{
$$hash{"author"} = new Bugzilla::User($$hash{"author_id"})->login;
}
delete $$hash{"author_id"};
$$hash{"product"} = "";
if (defined($$hash{"product_id"}))
{
$$hash{"product"} = new Bugzilla::Product($$hash{"product_id"})->name;
}
delete $$hash{"product_id"};
$$hash{"type"} = "";
if (defined($$hash{"type_id"}))
{
$$hash{"type"} = Bugzilla::Testopia::TestPlan->lookup_type($$hash{"type_id"});
}
delete $$hash{"type_id"};
}
# Utility method called by the list method
sub _list
{
@ -86,8 +34,6 @@ sub _list
my $cgi = Bugzilla->cgi;
$cgi->param("viewall", 1);
$cgi->param("current_tab", "plan");
foreach (keys(%$query))
@ -111,42 +57,38 @@ sub get
my $self = shift;
my ($test_plan_id) = @_;
Bugzilla->login;
# We can detaint immediately if what we get passed is fully numeric.
# We leave bug alias checks to Bugzilla::Testopia::TestPlan::new.
if ($test_plan_id =~ /^[0-9]+$/) {
detaint_natural($test_plan_id);
}
$self->login;
#Result is a test plan hash map
my $testplan = new Bugzilla::Testopia::TestPlan($test_plan_id);
my $test_plan = new Bugzilla::Testopia::TestPlan($test_plan_id);
if (not defined $test_plan)
{
$self->logout;
die "Testplan, " . $test_plan_id . ", not found";
}
if (not $test_plan->canview)
{
$self->logout;
die "User Not Authorized";
}
_convert_to_strings($testplan);
Bugzilla->logout;
return $testplan;
$self->logout;
return $test_plan;
}
sub list
{
Bugzilla->login;
my $self = shift;
my ($query) = @_;
_convert_to_ids($query);
$self->login;
my $list = _list($query);
foreach (@$list)
{
_convert_to_strings($_);
}
Bugzilla->logout;
$self->logout;
return $list;
}
@ -156,16 +98,16 @@ sub create
my $self =shift;
my ($new_values) = @_;
Bugzilla->login;
$self->login;
_convert_to_ids($new_values);
my $test_plan = new Bugzilla::Testopia::TestPlan($new_values);
Bugzilla->logout;
my $result = $test_plan->store();
$self->logout;
# Result is new test plan id
return $test_plan->store();
return $result;
}
sub update
@ -173,18 +115,154 @@ sub update
my $self =shift;
my ($test_plan_id, $new_values) = @_;
Bugzilla->login;
$self->login;
my $test_plan = new Bugzilla::Testopia::TestPlan($test_plan_id);
if (not defined $test_plan)
{
$self->logout;
die "Testplan, " . $test_plan_id . ", not found";
}
if (not $test_plan->canedit)
{
$self->logout;
die "User Not Authorized";
}
my $result = $test_plan->update($new_values);
$self->logout;
_convert_to_ids($new_values);
$test_plan->update($new_values);
Bugzilla->logout;
# Result is zero on success, otherwise an exception will be thrown
return 0;
return $test_plan;
}
sub get_test_cases
{
my $self =shift;
my ($test_plan_id) = @_;
$self->login;
my $test_plan = new Bugzilla::Testopia::TestPlan($test_plan_id);
if (not defined $test_plan)
{
$self->logout;
die "Testplan, " . $test_plan_id . ", not found";
}
if (not $test_plan->canview)
{
$self->logout;
die "User Not Authorized";
}
my $result = $test_plan->test_cases();
$self->logout;
# Result is list of test cases for the given test plan
return $result;
}
sub get_test_runs
{
my $self =shift;
my ($test_plan_id) = @_;
$self->login;
my $test_plan = new Bugzilla::Testopia::TestPlan($test_plan_id);
if (not defined $test_plan)
{
$self->logout;
die "Testplan, " . $test_plan_id . ", not found";
}
if (not $test_plan->canview)
{
$self->logout;
die "User Not Authorized";
}
my $result = $test_plan->test_runs();
$self->logout;
# Result is list of test runs for the given test plan
return $result;
}
sub get_categories
{
my $self =shift;
my ($test_plan_id) = @_;
$self->login;
my $test_plan = new Bugzilla::Testopia::TestPlan($test_plan_id);
if (not defined $test_plan)
{
$self->logout;
die "Testplan, " . $test_plan_id . ", not found";
}
if (not $test_plan->canview)
{
$self->logout;
die "User Not Authorized";
}
my $result = $test_plan->product->categories();
$self->logout;
# Result is list of test runs for the given test plan
return $result;
}
sub lookup_type_name_by_id
{
my $self =shift;
my ($id) = @_;
$self->login;
my $test_plan = new Bugzilla::Testopia::TestPlan({});
my $result = $test_plan->lookup_type($id);
$self->logout;
# Result is test plan type name for the given test plan type id
return $result;
}
sub lookup_type_id_by_name
{
my $self =shift;
my ($name) = @_;
$self->login;
my $test_plan = new Bugzilla::Testopia::TestPlan({});
my $result = $test_plan->lookup_type_by_name($name);
$self->logout;
if (!defined $result)
{
$result = 0;
};
# Result is test plan type id for the given test plan type name
return $result;
}
1;

View File

@ -0,0 +1,58 @@
# -*- 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>
# Dallas Harken <dharken@novell.com>
package Bugzilla::WebService::User;
use strict;
use Bugzilla;
use base qw(Bugzilla::WebService);
sub lookup_login_by_id
{
my $self = shift;
my ($author_id) = @_;
$self->login;
my $user = new Bugzilla::User($author_id);
my $result = defined $user ? $user->login : '';
$self->logout;
# Result is user login string or empty string if failed
return $result;
}
sub lookup_id_by_login
{
my $self = shift;
my ($author) = @_;
$self->login;
my $result = Bugzilla::User::login_to_id($author);
$self->logout;
# Result is user id or 0 if failed
return $result;
}
1;

View File

@ -20,7 +20,7 @@
#%]
[% PROCESS global/header.html.tmpl
title = "Product Builds for $plan.product_name"
title = "Product Builds for $plan.product.name"
%]
<table>
@ -31,7 +31,7 @@
<th class="bz_row_header" align="right">Actions</th>
</tr>
[% FOREACH cat = plan.builds %]
[% FOREACH cat = plan.product.builds %]
<tr>
<td valign="top">[% cat.name FILTER html %]</td>
<td valign="top">[% cat.milestone FILTER html %]</td>

View File

@ -0,0 +1,88 @@
[%# 1.0@bugzilla.org %]
[%# 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 Test Runner System.
#
# The Initial Developer of the Original Code is Maciej Maczynski.
# Portions created by Maciej Maczynski are Copyright (C) 2001
# Maciej Maczynski. All Rights Reserved.
#
# Contributor(s): Ed Fuentetaja <efuentetaja@acm.org>
# David Koenig <dkoenig@novell.com>
#%]
[%# Testopia Test Case CSV row export template #%]
[% PROCESS global/variables.none.tmpl %]
[% colsepchar = user.settings.csv_colsepchar.value %]
[% FOREACH column = displaycolumns %]
[% SWITCH column %]
[% CASE 'action' %]
[% case.text.action FILTER csv %]
[% CASE 'author_id' %]
[% case.author.email FILTER csv %]
[% CASE 'blocks' %]
[% case.blocked_list FILTER csv %]
[% CASE 'break_down' %]
[% case.text.breakdown FILTER csv %]
[% CASE 'case_status_id' %]
[% case.status FILTER csv %]
[% CASE 'category_id' %]
[% case.category.name FILTER csv %]
[% CASE 'components' %]
[% FILTER csv %]
[% FOREACH component = case.components %]
[% component.name %](product=[% component.product_name %])
[% IF component != case.components.last %]
[% colsepchar %]
[% END %]
[% END %]
[% END %]
[% CASE 'default_tester_id' %]
[% case.default_tester.email FILTER csv %]
[% CASE 'depends_on' %]
[% case.dependson_list FILTER csv %]
[% CASE 'expected_results' %]
[% case.text.effect FILTER csv %]
[% CASE 'isautomated' %]
[% case.isautomated ? "YES" : "NO" FILTER csv %]
[% CASE 'plans' %]
[% FILTER csv %]
[% FOREACH plan = case.plans %]
[% plan.id %]
[% IF plan != case.plans.last %]
[% colsepchar %]
[% END %]
[% END %]
[% END %]
[% CASE 'priority_id' %]
[% case.priority FILTER csv %]
[% CASE 'set_up' %]
[% case.text.setup FILTER csv %]
[% CASE 'tags' %]
[% FILTER csv %]
[% FOREACH tag = case.tags %]
[% tag.name %]
[% IF tag != case.tags.last %]
[% colsepchar %]
[% END %]
[% END %]
[% END %]
[% CASE DEFAULT %]
[% case.$column FILTER csv %]
[% END %]
[% IF column != displaycolumns.last %]
[% colsepchar %]
[% END %]
[% END %]

View File

@ -0,0 +1,38 @@
[%# 1.0@bugzilla.org %]
[%# 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 Test Runner System.
#
# The Initial Developer of the Original Code is Maciej Maczynski.
# Portions created by Maciej Maczynski are Copyright (C) 2001
# Maciej Maczynski. All Rights Reserved.
#
# Contributor(s): Ed Fuentetaja <efuentetaja@acm.org>
# David Koenig <dkoenig@novell.com>
#%]
[%# Testopia Test Case CSV column header export template #%]
[% PROCESS global/variables.none.tmpl %]
[% colsepchar = user.settings.csv_colsepchar.value %]
[% FOREACH column = displaycolumns %]
[% IF column == 'case_id' %]
[% column FILTER csv %]
[% ELSE %]
[% column FILTER remove('_id') FILTER csv %]
[% END %]
[% IF column != displaycolumns.last %]
[% colsepchar %]
[% END %]
[% END %]

View File

@ -25,7 +25,8 @@
[% IF case.canedit %]
<script type="text/javascript">
dojo.require("dojo.widget.Editor2");
dojo.require("dojo.widget.Editor2");
dojo.require("dojo.widget.Editor2Plugin.DialogCommands");
</script>
[% END %]
<a name="attributes"></a>

View File

@ -0,0 +1,34 @@
[%# 1.0@bugzilla.org %]
[%# 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 Test Runner System.
#
# The Initial Developer of the Original Code is Maciej Maczynski.
# Portions created by Maciej Maczynski are Copyright (C) 2001
# Maciej Maczynski. All Rights Reserved.
#
# Contributor(s): Ed Fuentetaja <efuentetaja@acm.org>
# David Koenig <dkoenig@novell.com>
#%]
[%# Testopia Test Case list CSV export template #%]
[% PROCESS global/variables.none.tmpl %]
[% colsepchar = user.settings.csv_colsepchar.value %]
[% PROCESS testopia/case/csv.header.tmpl %]
[% FOREACH test_case = table.list %]
[% PROCESS testopia/case/csv.case.tmpl case=test_case %]
[% END %]

View File

@ -193,6 +193,15 @@ found.
[% END %]
</form>
<div id="buglist_actions">
<div class="links">
<span class="label">Export:</span>
<a href="tr_list_cases.cgi?
[% urlquerypart FILTER remove('&viewall=.') FILTER html %]&amp;ctype=csv&amp;viewall=1"><image src="testopia/img/csv.png" class="image"></a>
</div>
</div>
[%############################################################################%]
[%# Page Footer #%]
[%############################################################################%]

View File

@ -0,0 +1,32 @@
[%# 1.0@bugzilla.org %]
[%# 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 Test Runner System.
#
# The Initial Developer of the Original Code is Maciej Maczynski.
# Portions created by Maciej Maczynski are Copyright (C) 2001
# Maciej Maczynski. All Rights Reserved.
#
# Contributor(s): Ed Fuentetaja <efuentetaja@acm.org>
# David Koenig <dkoenig@novell.com>
#%]
[%# Testopia Test Case CSV export template #%]
[% PROCESS global/variables.none.tmpl %]
[% USE date %]
[% colsepchar = user.settings.csv_colsepchar.value %]
[% PROCESS testopia/case/csv.header.tmpl %]
[% PROCESS testopia/case/csv.case.tmpl%]

View File

@ -301,6 +301,17 @@
[% END %]
</FORM>
<div id="buglist_actions">
<div class="links">
<span class="label">Export:</span>
<a href="tr_show_case.cgi?
&amp;case_id=[% case.id FILTER none %]&amp;ctype=csv"><image src="images/csv.png" class="image"></a>
[%# <img src="https://secure-www.novell.com/img/link_divbar.gif" width="1" height="20" alt="line" class="bar"> #%]
[%# <a href="tr_list_cases.cgi? #%]
[%# &amp;ctype=xml"><image src="images/xml.png" class="image"></a> #%]
</div>
</div>
[%##### Footer #####%]
[% PROCESS global/footer.html.tmpl %]

View File

@ -24,7 +24,7 @@
#%]
[% IF NOT dotweak %]
[% build_list = caserun.run.plan.builds %]
[% build_list = caserun.run.plan.product.builds %]
[% default_build = caserun.build.name %]
[% ELSE %]
[% default_build = "--Do Not Change--" %]
@ -88,7 +88,7 @@
<th align="right">Assignee</th>
<td><input name="assignee" value="[% dotweak ? "--Do Not Change--" : caserun.assignee.login FILTER html %]"></td>
<th align="right" valign="top" colspan="2">Attach [% terms.Bugs %]</th>
<td><input name="bugs">&nbsp;<a href="enter_bug.cgi?product=[% caserun.run.plan.product_name FILTER url_quote %]&caserun_id=[% caserun.id FILTER none %]">Log a New [% terms.Bug %]</a></td>
<td><input name="bugs">&nbsp;<a href="enter_bug.cgi?product=[% caserun.run.plan.product.name FILTER url_quote %]&caserun_id=[% caserun.id FILTER none %]">Log a New [% terms.Bug %]</a></td>
</tr>
</table>

View File

@ -39,7 +39,7 @@
<td align="left"><a href="tr_show_case.cgi?case_id=[% caserun.case.id FILTER none %]" title="[% caserun.case.summary FILTER html %]">[% caserun.case.id FILTER html %]</a></td>
<td align="right" valign="top">
[% PROCESS select sel = { name => "caserun_build",
list => caserun.run.plan.builds,
list => caserun.run.plan.product.builds,
default => caserun.build.name
events => "onChange='chBld($index, this.value, \"$caserun.status\", $caserun.id)'"}
%]

View File

@ -116,7 +116,7 @@
</span>]
</div>
<div class="cc_i">
<a href="enter_bug.cgi?product=[% caserun.run.plan.product_name FILTER url_quote %]&caserun_id=[% caserun.id FILTER none %]&version=[% caserun.run.plan.product_version FILTER url_quote %]&component=[% caserun.case.components.0.name FILTER url_quote %]&short_desc=Test%20Case%20[% caserun.case.id FILTER none %]%20-%20[% caserun.case.summary FILTER url_quote %]&comment=STATUS:%20[% caserun.status %]%0D%0ABUILD:%20[% caserun.build.name FILTER url_quote %]%0D%0AENVIRONMENT:%20[% caserun.environment.name FILTER url_quote %]%0D%0ANOTES:%20[% caserun.notes FILTER url_quote %]%0D%0A&assigned_to=[% caserun.case.components.0.default_assignee.login FILTER url_quote %]&qa_contact=[% caserun.case.components.0.default_qa_contact.login FILTER url_quote %]" target="_blank"><img src="testopia/img/snew.gif" alt="Log a New Bug" title="Log a New Bug" style="vertical-align:text-bottom;" /></a>&nbsp;
<a href="enter_bug.cgi?product=[% caserun.run.plan.product.name FILTER url_quote %]&caserun_id=[% caserun.id FILTER none %]&version=[% caserun.run.plan.product_version FILTER url_quote %]&component=[% caserun.case.components.0.name FILTER url_quote %]&short_desc=Test%20Case%20[% caserun.case.id FILTER none %]%20-%20[% caserun.case.summary FILTER url_quote %]&comment=STATUS:%20[% caserun.status %]%0D%0ABUILD:%20[% caserun.build.name FILTER url_quote %]%0D%0AENVIRONMENT:%20[% caserun.environment.name FILTER url_quote %]%0D%0ANOTES:%20[% caserun.notes FILTER url_quote %]%0D%0A&assigned_to=[% caserun.case.components.0.default_assignee.login FILTER url_quote %]&qa_contact=[% caserun.case.components.0.default_qa_contact.login FILTER url_quote %]" target="_blank"><img src="testopia/img/snew.gif" alt="Log a New Bug" title="Log a New Bug" style="vertical-align:text-bottom;" /></a>&nbsp;
</div>
<div style="float:left;"><input type="text" size="6" value="" id="mbg[% index %]" [% enabled %]
[% IF caserun.canedit %]

View File

@ -66,7 +66,7 @@
</tr>
<tr class="bz_row_data">
<td>[% caserun.case.version FILTER html %]</td>
<td>[% caserun.run.plan.product_name FILTER html %]</td>
<td>[% caserun.run.plan.product.name FILTER html %]</td>
<td>[% caserun.close_date FILTER html %]</td>
</tr>
<tr class="bz_row_header">

View File

@ -20,7 +20,7 @@
#%]
[% PROCESS global/header.html.tmpl
title = "Delete Category $category.name From Product $plan.product_name"
title = "Delete Category $category.name From Product $plan.product.name"
%]
<form method="POST" action="tr_categories.cgi">

View File

@ -20,7 +20,7 @@
#%]
[% PROCESS global/header.html.tmpl
title = "Test Categories for $plan.product_name"
title = "Test Categories for $plan.product.name"
%]
<table>
<tr>
@ -28,7 +28,7 @@
<th class="bz_row_header" align="right">Description</th>
<th class="bz_row_header" align="right">Actions</th>
</tr>
[% FOREACH cat = plan.categories %]
[% FOREACH cat = plan.product.categories %]
<tr>
<td valign="top">[% cat.name FILTER html %]</td>
<td valign="top">[% cat.description FILTER html %]</td>

View File

@ -92,7 +92,7 @@
categories only:</td>
<td>
[% PROCESS select sel = { name => 'clone_categories',
list => plan.categories
list => plan.product.categories
accesskey => 'c'
mult => 1
elements => 5

View File

@ -23,6 +23,7 @@
<script type="text/javascript">
dojo.require("dojo.io");
dojo.require("dojo.widget.Editor2");
dojo.require("dojo.widget.Editor2Plugin.DialogCommands");
</script>
<a name="attributes"></a>
<input type="hidden" name="plan_id" value="[% plan.id FILTER none %]">
@ -35,7 +36,7 @@
<th class="bz_row_header" align="right" width="100">Product</th>
<td>[% IF plan.test_case_count OR plan.test_run_count %]
<input type="hidden" name='product_id' value="[% plan.product_id FILTER none %]" />
[% plan.product_name FILTER html %]
[% plan.product.name FILTER html %]
[% ELSE %]
[% PROCESS select sel = { name => 'product_id',
list => plan.get_available_products,

View File

@ -37,7 +37,7 @@
<table>
<tr>
<td class="caption">Product:</td>
<td>[% plan.product_name FILTER html %]</td>
<td>[% plan.product.name FILTER html %]</td>
<td class="caption">Product version:</td>
<td>[% plan.product_version FILTER html %]</td>
</tr>

View File

@ -137,7 +137,7 @@
<th>Created</th>
</tr>
<tr class="bz_row_data">
<td>[% plan.product_name FILTER html %]</td>
<td>[% plan.product.name FILTER html %]</td>
<td>[% plan.product_version FILTER html %]</td>
<td>[% plan.creation_date FILTER time %]</td>
</tr>
@ -181,7 +181,7 @@
<tr>
<td align="left">
[% PROCESS select sel = { name => 'category',
list => plan.categories
list => plan.product.categories
accesskey => 'c'
elements => 7 } %]
<br>
@ -200,7 +200,7 @@
</td>
<td align="right">
[% PROCESS select sel = { name => 'build',
list => plan.builds
list => plan.product.builds
accesskey => 'b'
elements => 7 } %]
<br>

View File

@ -52,7 +52,7 @@ Select:
<td><a href="tr_show_plan.cgi?plan_id=[% plan.plan_id FILTER none %]">[% plan.name FILTER html %]</a></td>
<td>[% plan.author.login FILTER html %]</td>
<td>[% plan.creation_date FILTER time %]</td>
<td>[% plan.product_name FILTER html%]</td>
<td>[% plan.product.name FILTER html%]</td>
<td>[% plan.product_version FILTER html%]</td>
<td align="center">[% plan.plan_type FILTER html %]</td>
<td align="center">

View File

@ -69,7 +69,7 @@
<tr>
<td valign="TOP" align="RIGHT">Build:</td>
<td>[% PROCESS select sel = { name => 'build',
list => run.plan.builds
list => run.plan.product.builds
accesskey => 'b'
default => run.build.id } %]</td>
</tr>

View File

@ -71,7 +71,7 @@
<th align="right"><a href="tr_builds.cgi?plan_id=[% run.plan.id FILTER none %]">Build</a></td>
<td>
[% PROCESS select sel = { name => "build",
list => run.plan.builds,
list => run.plan.product.builds,
default => run.build.id }
%]
[% IF action == 'Add' %]

View File

@ -127,7 +127,7 @@
<th>Stop Date</th>
</tr>
<tr class="bz_row_data">
<td>[% run.plan.product_name FILTER html %]</td>
<td>[% run.plan.product.name FILTER html %]</td>
<td>[% run.product_version FILTER html %]</td>
<td>[% run.stop_date FILTER time %]</td>
</tr>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -183,7 +183,7 @@ else {
sub get_builds_xml {
my ($plan) = @_;
my $ret = "<items>";
foreach my $c (@{$plan->builds}){
foreach my $c (@{$plan->product->builds}){
$ret .= "<build>";
$ret .= "<id>". $c->id ."</id>";
$ret .= "<name>". $c->name ."</name>";

View File

@ -58,7 +58,7 @@ ThrowUserError("testopia-read-only", {'object' => 'Plan'}) unless $plan->canedit
if ($action eq 'add'){
$vars->{'plan'} = $plan;
$vars->{'action'} = 'do_add';
$vars->{'title'} = "Create a New Category for ". $plan->product_name;
$vars->{'title'} = "Create a New Category for ". $plan->product->name;
$template->process("testopia/category/form.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
}
@ -171,7 +171,7 @@ else {
sub get_categories_xml {
my ($plan) = @_;
my $ret = "<items>";
foreach my $c (@{$plan->categories}){
foreach my $c (@{$plan->product->categories}){
$ret .= "<category>";
$ret .= "<id>". $c->id ."</id>";
$ret .= "<name>". $c->name ."</name>";

View File

@ -184,8 +184,8 @@ sub remove_field_list
s/\342\200\246/&#133;/g;
s/\342\200\223/-/g;
s/\342\200\224/&#8212;/g;
s/\342\200\234/&#8221;/g;
s/\342\200\235/&#8222;/g;
s/\342\200\234/&#8220;/g;
s/\342\200\235/&#8221;/g;
s/\302\251/&copy;/g;
s/\031/'/g;
s/\221/&apos;/g;
@ -228,6 +228,10 @@ sub remove_field_list
next;
}
# Missing or empty environment in TCDB has this value in the environment field. Set it to
# null and hope it was not in the middle of a field.
s/"\$EMPTYENV"/""/;
# TCDB CSV options that are not handled correctly:
# If a field contains some thing like:
# '2. Click "Roles and Tasks " , "Storage" , click "Volumes" and''
@ -545,7 +549,6 @@ foreach my $line (@{$csv->lines()}) {
if ( defined($fields{'environment'}) )
{
my $environment = $line->environment();
$environment = "" if ( $environment eq "\$EMPTYENV" );
$summary .= " - " . fix_entities($environment) if ( $environment ne "" );
}
error("No summary for Test Case at line $line_count in $csv_work_filename") if ( $summary eq "" );
@ -574,6 +577,7 @@ foreach my $line (@{$csv->lines()}) {
if ( defined($fields{'environment'}) )
{
my @environments = split(/,/,$line->environment());
foreach my $environment (@environments)
{
print XMLOUTPUT " <tag>" . fix_entities(remove_white_space($environment)) . "</tag>\n";

View File

@ -241,7 +241,7 @@ if ($table->list_count > 0){
}
if (!$vars->{'multiprod'}){
my $p = $table->list->[0]->run->plan;
my $build_list = $p->builds;
my $build_list = $p->product->builds;
unshift @{$build_list}, {'id' => -1, 'name' => "--Do Not Change--"};
$vars->{'build_list'} = $build_list;
}

View File

@ -49,8 +49,14 @@ $cgi->send_cookie(-name => "TEST_LAST_ORDER",
-expires => "Fri, 01-Jan-2038 00:00:00 GMT");
Bugzilla->login();
# Determine the format in which the user would like to receive the output.
# Uses the default format if the user did not specify an output format;
# otherwise validates the user's choice against the list of available formats.
my $format = $template->get_format("testopia/case/list", scalar $cgi->param('format'), scalar $cgi->param('ctype'));
my $action = $cgi->param('action') || '';
my $serverpush = support_server_push($cgi);
my $serverpush = ( support_server_push($cgi) ) && ( $format->{'extension'} eq "html" );
if ($serverpush) {
print $cgi->multipart_init;
print $cgi->multipart_start;
@ -58,9 +64,7 @@ if ($serverpush) {
$template->process("list/server-push.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
}
else {
print $cgi->header;
}
# prevent DOS attacks from multiple refreshes of large data
$::SIG{TERM} = 'DEFAULT';
$::SIG{PIPE} = 'DEFAULT';
@ -262,11 +266,43 @@ $vars->{'status_list'} = $status_list;
$vars->{'priority_list'} = $priority_list;
$vars->{'dotweak'} = UserInGroup('edittestcases');
$vars->{'table'} = $table;
$vars->{'urlquerypart'} = $cgi->canonicalise_query('cmdtype');
my $contenttype;
if ($format->{'extension'} eq "html") {
$contenttype = "text/html";
}
else {
$contenttype = $format->{'ctype'};
}
if ($serverpush && !$cgi->param('debug')) {
print $cgi->multipart_end;
print $cgi->multipart_start;
}
$template->process("testopia/case/list.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
}
else {
my @time = localtime(time());
my $date = sprintf "%04d-%02d-%02d", 1900+$time[5],$time[4]+1,$time[3];
my $filename = "testcases-$date.$format->{extension}";
my $disp = "inline";
# We set CSV files to be downloaded, as they are designed for importing
# into other programs.
if ($format->{'extension'} eq "csv")
{
$disp = "attachment";
$vars->{'displaycolumns'} = \@Bugzilla::Testopia::Constants::TESTCASE_EXPORT;
}
# Suggest a name for the bug list if the user wants to save it as a file.
# If we are doing server push, then we did this already in the HTTP headers
# that started the server push, so we don't have to do it again here.
print $cgi->header(-type => $contenttype,
-content_disposition => "$disp; filename=$filename");
}
$template->process($format->{'template'}, $vars)
|| ThrowTemplateError($template->error());
print $cgi->multipart_final if $serverpush;

View File

@ -152,7 +152,7 @@ else {
}
if (!$vars->{'multiprod'}) {
my $p = $table->list->[0]->plan;
my $build_list = $p->builds;
my $build_list = $p->product->builds;
unshift @{$build_list}, {'id' => -1, 'name' => "--Do Not Change--"};
$vars->{'build_list'} = $build_list;
}

View File

@ -70,7 +70,7 @@ foreach my $id (keys %seen){
my $plan = Bugzilla::Testopia::TestPlan->new($id);
push @plan_ids, $id;
push @plans, $plan;
push @categories, @{$plan->categories};
push @categories, @{$plan->product->categories};
}
ThrowUserError('testopia-create-category', {'plan' => $plans[0] }) if scalar @categories < 1;

View File

@ -63,7 +63,7 @@ detaint_natural($plan_id);
validate_test_id($plan_id, 'plan');
my $plan = Bugzilla::Testopia::TestPlan->new($plan_id);
unless (scalar @{$plan->builds} >0){
unless (scalar @{$plan->product->builds} >0){
print $cgi->header;
ThrowUserError('testopia-create-build', {'plan' => $plan});
}

View File

@ -43,19 +43,28 @@ my $query_limit = 15000;
require "globals.pl";
Bugzilla->login();
print Bugzilla->cgi->header();
my $dbh = Bugzilla->dbh;
my $cgi = Bugzilla->cgi;
my $case_id = trim(Bugzilla->cgi->param('case_id')) || '';
unless ($case_id){
$template->process("testopia/case/choose.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
print $cgi->header();
$template->process("testopia/case/choose.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
exit;
}
validate_test_id($case_id, 'case');
my $format = $template->get_format("testopia/case/show", scalar $cgi->param('format'), scalar $cgi->param('ctype'));
unless ( $format->{'extension'} eq "html" ){
export($case_id);
exit;
}
print $cgi->header();
$vars->{'action'} = "Commit";
$vars->{'form_action'} = "tr_show_case.cgi";
@ -395,3 +404,38 @@ sub display {
$template->process("testopia/case/show.html.tmpl", $vars) ||
ThrowTemplateError($template->error());
}
sub export {
my ($case_id) = @_;
my $case = Bugzilla::Testopia::TestCase->new($case_id);
ThrowUserError("testopia-permission-denied", {'object' => 'case'}) unless $case->canview;
$cgi->param('case_id', $case->id);
$cgi->param('isactive', 1);
$cgi->param('current_tab', 'case_run');
my $search = Bugzilla::Testopia::Search->new($cgi);
my $table = Bugzilla::Testopia::Table->new('case_run', 'tr_show_case.cgi', $cgi, undef, $search->query);
$vars->{'case'} = $case;
$vars->{'table'} = $table;
$vars->{'user'} = Bugzilla->user;
my $disp = "inline";
# We set CSV files to be downloaded, as they are designed for importing
# into other programs.
if ($format->{'extension'} eq "csv")
{
$disp = "attachment";
$vars->{'displaycolumns'} = \@Bugzilla::Testopia::Constants::TESTCASE_EXPORT;
}
# Suggest a name for the bug list if the user wants to save it as a file.
# If we are doing server push, then we did this already in the HTTP headers
# that started the server push, so we don't have to do it again here.
my @time = localtime(time());
my $date = sprintf "%04d-%02d-%02d", 1900+$time[5],$time[4]+1,$time[3];
my $filename = "testcase-$case_id-$date.$format->{extension}";
print $cgi->header(-type => $format->{'ctype'},
-content_disposition => "$disp; filename=$filename");
$template->process($format->{'template'}, $vars) ||
ThrowTemplateError($template->error());
}