bzrmirror%bugzilla.org 7f19af5d02 Bug 743652 (part 6: tr_run_reports.cgi): Move all tr_*.cgi code into Extension.pm
r=LpSolit


git-svn-id: svn://10.0.0.236/trunk@265922 18797224-902f-48f8-a5cc-f745e15eee43
2015-04-13 02:00:22 +00:00

424 lines
17 KiB
Perl

package Bugzilla::Extension::Testopia;
use strict;
use warnings;
use base qw(Bugzilla::Extension);
use Bugzilla::Extension::Testopia::Constants;
use Bugzilla::Extension::Testopia::Install;
use Bugzilla::Extension::Testopia::Product;
use Bugzilla::Extension::Testopia::TestCase;
use Bugzilla::Extension::Testopia::TestPlan;
use Bugzilla::Extension::Testopia::TestRun;
use Bugzilla::Constants;
use Bugzilla::Group;
use Bugzilla::Status;
use Bugzilla::User::Setting;
use Bugzilla::Util;
use File::Path;
use JSON;
BEGIN {
*Bugzilla::Bug::get_test_case_count = \&get_test_case_count;
*Bugzilla::User::testopia_queries = \&testopia_queries;
# We must redefine these two methods.
undef &Bugzilla::User::get_selectable_products;
undef &Bugzilla::User::derive_regexp_groups;
*Bugzilla::User::get_selectable_products = \&get_selectable_products;
*Bugzilla::User::derive_regexp_groups =\&derive_regexp_groups;
}
our $VERSION = '2.6';
sub WS_EXECUTE { Bugzilla->localconfig->{'webservergroup'} ? 0750 : 0755 };
# The subroutines below are used in the BEGIN block above to extend
# or redefine some methods in Bugzilla::Bug and Bugzilla::User.
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;
}
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 get_selectable_products {
my $self = shift;
my $class_id = shift;
my $class_restricted = Bugzilla->params->{'useclassification'} && $class_id;
if (!defined $self->{selectable_products}) {
my $query = "(SELECT id, name AS pname " .
" FROM products " .
"LEFT JOIN group_control_map " .
"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) " ;
$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);
}
# Restrict the list of products to those being in the classification, if any.
if ($class_restricted) {
return [grep {$_->classification_id == $class_id} @{$self->{selectable_products}}];
}
# If we come here, then we want all selectable products.
return $self->{selectable_products};
}
sub derive_regexp_groups {
my ($self) = @_;
my $id = $self->id;
return unless $id;
my $dbh = Bugzilla->dbh;
my $sth;
# add derived records for any matching regexps
$sth = $dbh->prepare("SELECT id, userregexp, user_group_map.group_id
FROM groups
LEFT JOIN user_group_map
ON groups.id = user_group_map.group_id
AND user_group_map.user_id = ?
AND user_group_map.grant_type = ?");
$sth->execute($id, GRANT_REGEXP);
my $group_insert = $dbh->prepare(q{INSERT INTO user_group_map
(user_id, group_id, isbless, grant_type)
VALUES (?, ?, 0, ?)});
my $group_delete = $dbh->prepare(q{DELETE FROM user_group_map
WHERE user_id = ?
AND group_id = ?
AND isbless = 0
AND grant_type = ?});
while (my ($group, $regexp, $present) = $sth->fetchrow_array()) {
if (($regexp ne '') && ($self->login =~ m/$regexp/i)) {
$group_insert->execute($id, $group, GRANT_REGEXP) unless $present;
} else {
$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;
}
}
}
# End of redefined subroutines.
sub bug_end_of_update {
my ($self, $args) = @_;
my $bug = $args->{'bug'};
my $timestamp = $args->{'timestamp'};
my $changes = $args->{'changes'};
my $dbh = Bugzilla->dbh;
foreach my $field (keys %$changes) {
my $used_to_be = $changes->{$field}->[0];
my $now_it_is = $changes->{$field}->[1];
}
my $tcrs = $dbh->selectcol_arrayref("SELECT case_id FROM test_case_bugs WHERE bug_id = ?", undef, $bug->id);
my $status_message;
if (my $status_change = $changes->{'bug_status'}) {
my $old_status = new Bugzilla::Status({ name => $status_change->[0] });
my $new_status = new Bugzilla::Status({ name => $status_change->[1] });
if ($new_status->is_open && !$old_status->is_open) {
for my $tcr(@$tcrs) {
my $tc = Bugzilla::Extension::Testopia::TestCase->new($tcr);
$tc->remove_tag('BUGFIXED');
}
}
if (!$new_status->is_open && $old_status->is_open) {
for my $tcr(@$tcrs) {
my $tc = Bugzilla::Extension::Testopia::TestCase->new($tcr);
$tc->add_tag('BUGFIXED');
}
}
}
}
sub buglist_columns {
my ($self, $args) = @_;
my $columns = $args->{'columns'};
$columns->{'test_cases'} = { 'name' => 'tcb.case_id' , 'title' => 'Test Cases' };
}
sub buglist_column_joins {
my ($self, $args) = @_;
my $joins = $args->{column_joins};
$joins->{test_cases} = { table => 'test_case_bugs', as => 'tcb' };
}
sub config_add_panels {
my ($self, $args) = @_;
my $modules = $args->{panel_modules};
$modules->{Testopia} = "Bugzilla::Extension::Testopia::Config";
}
sub db_schema_abstract_schema {
my ($self, $args) = @_;
my $schema = $args->{schema};
Bugzilla::Extension::Testopia::Install::set_db_schema_abstract_schema($schema);
}
sub enter_bug_entrydefaultvars {
my ($self, $args) = @_;
my $vars = $args->{vars};
my $cgi = Bugzilla->cgi;
$vars->{'case_id'} = $cgi->param('case_id');
$vars->{'caserun_id'} = $cgi->param('caserun_id');
}
sub error_catch {
my ($self, $args) = @_;
return unless Bugzilla->error_mode == ERROR_MODE_AJAX;
# JSON can't handle strings across lines.
my $message = ${$args->{message}};
$message =~ s/\n/ /gm;
my $err = { success => JSON::false,
error => $args->{error},
message => $message };
my $json = new JSON;
print $json->encode($err);
exit;
}
sub install_before_final_checks {
my ($self, $args) = @_;
add_setting('view_testopia', ['on', 'off'], 'on');
if ( -e './testopia/patch-3.2'){
print <<END;
WARNING:
We are about to remove the old Testopia files that have been moved
to the extensions directory. If you have made any changes to Testopia
you should first merge these changes into the equivilent files in the
extensions/Testopia directory. Here are a list of files that are changing
and their new locations:
testopia (dir) -> extensions/Testopia/
Bugzilla/Testopia/ (dir) -> extensions/Testopia/lib
Bugzilla/WebService/Testopia/ (dir) -> extensions/Testopia/lig/WebService
Bugzilla/Config/Testopia.pm -> extensions/Testopia/lib/Testopia/Config.pm
skins/standard/testopia.css -> extensions/Testopia/css/testopia.css
template/en/default/testopia/ (dir) -> extensions/Testopia/template/en/default
The following templates and template hooks have been moved to the
extensions/Testopia/template directory:
template/en/default/admin/params/testopia.html.tmpl
template/en/default/hook/admin/products/confirm-delete.html.tmpl
template/en/default/hook/admin/products/confirm-delete.html.tmpl/confirmation/testopia.html.tmpl
template/en/default/hook/bug/create/created.html.tmpl/message/tr.html.tmpl
template/en/default/hook/bug/create/create.html.tmpl/end/tr.html.tmpl
template/en/default/hook/bug/create/create.html.tmpl/form/tr.html.tmpl
template/en/default/hook/bug/edit.html.tmpl/after_custom_fields/tr.html.tmpl
template/en/default/hook/bug/process/results.html.tmpl/links/tr.html.tmpl
template/en/default/hook/global/banner.html.tmpl/version/testopia.html.tmpl
template/en/default/hook/global/code-error.html.tmpl/errors/testopia_errors.html.tmpl
template/en/default/hook/global/common-links.html.tmpl/link-row/testopia.html.tmpl
template/en/default/hook/global/header.html.tmpl/additional_header/testopia_styles.html.tmpl
template/en/default/hook/global/useful-links.html.tmpl/end/tr.html.tmpl
template/en/default/hook/global/user-error.html.tmpl/errors/tr-user-error.html.tmpl
template/en/default/hook/index.html.tmpl/links/tr.html.tmpl
template/en/default/hook/list/list.html.tmpl/links/tr.html.tmpl
The following files are no longer needed and will be removed:
testopia.dtd (use extensions/Testopia/testopia.xsd instead)
tr_csv2xml.pl (use tr_importer.cgi instead)
tr_xmlrpc.cgi (use bugzilla's xmlrpc or create a link to it)
If you have changes to merge, you should answer NO. Otherwise answer YES.
Do you wish to continue and delete these files? (YES/no)
END
my $response = <STDIN>;
die "Exiting... \n" if $response !~ /y/i;
my @files = qw(
testopia
testopia.dtd
tr_csv2xml.pl
tr_xmlrpc.cgi
Bugzilla/Testopia/
Bugzilla/WebService/Testopia/
Bugzilla/Config/Testopia.pm
skins/standard/testopia.css
template/en/default/testopia/
template/en/default/admin/params/testopia.html.tmpl
template/en/default/hook/admin/products/confirm-delete.html.tmpl
template/en/default/hook/admin/products/confirm-delete.html.tmpl/confirmation/testopia.html.tmpl
template/en/default/hook/bug/create/created.html.tmpl/message/tr.html.tmpl
template/en/default/hook/bug/create/create.html.tmpl/end/tr.html.tmpl
template/en/default/hook/bug/create/create.html.tmpl/form/tr.html.tmpl
template/en/default/hook/bug/edit.html.tmpl/after_custom_fields/tr.html.tmpl
template/en/default/hook/bug/process/results.html.tmpl/links/tr.html.tmpl
template/en/default/hook/global/banner.html.tmpl/version/testopia.html.tmpl
template/en/default/hook/global/code-error.html.tmpl/errors/testopia_errors.html.tmpl
template/en/default/hook/global/common-links.html.tmpl/link-row/testopia.html.tmpl
template/en/default/hook/global/header.html.tmpl/additional_header/testopia_styles.html.tmpl
template/en/default/hook/global/useful-links.html.tmpl/end/tr.html.tmpl
template/en/default/hook/global/user-error.html.tmpl/errors/tr-user-error.html.tmpl
template/en/default/hook/index.html.tmpl/links/tr.html.tmpl
template/en/default/hook/list/list.html.tmpl/links/tr.html.tmpl
);
rmtree(@files, 1);
}
}
sub install_filesystem {
my ($self, $args) = @_;
$args->{'files'}->{'tr_importxml.pl'} = { perms => WS_EXECUTE };
}
sub install_update_db {
my ($self, $args) = @_;
Bugzilla::Extension::Testopia::Install::install_update_db();
}
sub page_before_template {
my ($self, $args) = @_;
my $page = $args->{'page_id'};
my $vars = $args->{'vars'};
if ($page eq 'tr_admin.html') {
require Bugzilla::Extension::Testopia::Admin;
Bugzilla::Extension::Testopia::Admin::report($vars);
}
elsif ($page eq 'tr_case_reports.html') {
require Bugzilla::Extension::Testopia::Reports::Case;
Bugzilla::Extension::Testopia::Reports::Case::report($vars);
}
elsif ($page eq 'tr_caserun_reports.html') {
require Bugzilla::Extension::Testopia::Reports::CaseRun;
Bugzilla::Extension::Testopia::Reports::CaseRun::report($vars);
}
elsif ($page eq 'tr_plan_reports.html') {
require Bugzilla::Extension::Testopia::Reports::Plan;
Bugzilla::Extension::Testopia::Reports::Plan::report($vars);
}
elsif ($page eq 'tr_product_reports.html') {
require Bugzilla::Extension::Testopia::Reports::Product;
Bugzilla::Extension::Testopia::Reports::Product::report($vars);
}
elsif ($page eq 'tr_run_reports.html') {
require Bugzilla::Extension::Testopia::Reports::Run;
Bugzilla::Extension::Testopia::Reports::Run::report($vars);
}
}
sub post_bug_after_creation {
my ($self, $args) = @_;
my $vars = $args->{vars};
my $cgi = Bugzilla->cgi;
my $caserun_id = $cgi->param('caserun_id');
my $case_id = $cgi->param('case_id');
if (detaint_natural($caserun_id)) {
my $caserun = Bugzilla::Extension::Testopia::TestCaseRun->new($cgi->param('caserun_id'));
ThrowUserError("invalid-test-id-non-existent", {'id' => $caserun_id, 'type' => 'Case-Run'}) unless $caserun;
ThrowUserError("testopia-read-only", {'object' => $caserun}) unless $caserun->canedit;
$caserun->attach_bug($vars->{'id'});
$vars->{'caserun'} = $caserun;
}
elsif (detaint_natural($case_id)) {
my $case = Bugzilla::Extension::Testopia::TestCase->new($cgi->param('case_id'));
ThrowUserError("invalid-test-id-non-existent", {'id' => $case_id, 'type' => 'Case'}) unless $case;
ThrowUserError("testopia-read-only", {'object' => $case}) unless $case->canedit;
$case->attach_bug($vars->{'id'});
$vars->{'case'} = $case;
}
}
sub product_confirm_delete {
my ($self, $args) = @_;
my $vars = $args->{vars};
$vars->{'testopia_product'} = new Bugzilla::Extension::Testopia::Product($vars->{product}->id);
}
sub webservice {
my ($self, $args) = @_;
my $dispatch = $args->{dispatch};
$dispatch->{TestPlan} = "Bugzilla::Extension::Testopia::WebService::TestPlan";
$dispatch->{TestCase} = "Bugzilla::Extension::Testopia::WebService::TestCase";
$dispatch->{TestRun} = "Bugzilla::Extension::Testopia::WebService::TestRun";
$dispatch->{TestCaseRun} = "Bugzilla::Extension::Testopia::WebService::TestCaseRun";
$dispatch->{Environment} = "Bugzilla::Extension::Testopia::WebService::Environment";
$dispatch->{Build} = "Bugzilla::Extension::Testopia::WebService::Build";
$dispatch->{Testopia} = "Bugzilla::Extension::Testopia::WebService::Testopia";
$dispatch->{TestopiaUser} = "Bugzilla::Extension::Testopia::WebService::User";
$dispatch->{TestopiaProduct} = "Bugzilla::Extension::Testopia::WebService::Product";
}
__PACKAGE__->NAME;