#!/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 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): Maciej Maczynski # Ed Fuentetaja # Greg Hendricks use strict; use lib "."; use Bugzilla; use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::Constants; use Bugzilla::Testopia::Util; use Bugzilla::Testopia::Classification; use Bugzilla::Testopia::TestPlan; use Bugzilla::Testopia::TestRun; use Bugzilla::Testopia::Environment::Category; use Bugzilla::Testopia::Environment::Element; use Bugzilla::Testopia::Environment::Property; use JSON; local our $vars = {}; my $dbh = Bugzilla->dbh; local our $cgi = Bugzilla->cgi; local our $template = Bugzilla->template; Bugzilla->login(LOGIN_REQUIRED); sub get_searchable_objects{ my $object = shift; my $dbh = Bugzilla->dbh; my $products = Bugzilla->user->get_selectable_products; my @ids; foreach my $p (@{$products}){ push @ids, $p->id; } my $ref; SWITCH: for ($object) { /^components/ && do { $ref = $dbh->selectall_arrayref( "SELECT DISTINCT name AS id, name FROM components WHERE product_id IN (". join(",",@ids) .") ORDER BY name", {'Slice'=>{}}); last SWITCH; }; /^categories/ && do { $ref = $dbh->selectall_arrayref( "SELECT DISTINCT name AS id, name FROM test_case_categories WHERE product_id IN (". join(",",@ids) .") ORDER BY name", {'Slice'=>{}}); last SWITCH; }; /^builds/ && do { $ref = $dbh->selectall_arrayref( "SELECT DISTINCT name AS id, name FROM test_builds WHERE product_id IN (". join(",",@ids) .") ORDER BY name", {'Slice'=>{}}); last SWITCH; }; /^versions/ && do { $ref = $dbh->selectall_arrayref( "SELECT DISTINCT value AS id, value AS name FROM versions WHERE product_id IN (". join(",",@ids) .") ORDER BY name", {'Slice'=>{}}); last SWITCH; }; /^milestones/ && do { $ref = $dbh->selectall_arrayref( "SELECT DISTINCT value AS id, value AS name FROM milestones WHERE product_id IN (". join(",",@ids) .") ORDER BY name", {'Slice'=>{}}); last SWITCH; }; /^environments/ && do { $ref = $dbh->selectall_arrayref( "SELECT DISTINCT name AS id, name FROM test_environments WHERE product_id IN (". join(",",@ids) .") ORDER BY name", {'Slice'=>{}}); last SWITCH; }; } return $ref; } print $cgi->header; my $action = $cgi->param('action') || ''; if ($action eq 'getversions'){ my @prod_ids = split(",", $cgi->param('prod_ids')); my $tab = $cgi->param('current_tab') || ''; my $plan = Bugzilla::Testopia::TestPlan->new({}); my $products; my @validated; foreach my $p (@prod_ids){ detaint_natural($p); validate_selection($p,'id','products'); my $prod = $plan->lookup_product($p); push @validated, $p if Bugzilla->user->can_see_product($prod); } my $prod_ids = join(",", @validated); my $dbh = Bugzilla->dbh; $products->{'version'} = $dbh->selectcol_arrayref("SELECT DISTINCT value FROM versions WHERE product_id IN ($prod_ids)"); $products->{'milestone'} = $dbh->selectcol_arrayref("SELECT DISTINCT value FROM milestones WHERE product_id IN ($prod_ids)"); $products->{'component'} = $dbh->selectcol_arrayref("SELECT DISTINCT name FROM components WHERE product_id IN ($prod_ids)"); $products->{'build'} = $dbh->selectcol_arrayref("SELECT DISTINCT name FROM test_builds WHERE product_id IN ($prod_ids)"); $products->{'category'} = $dbh->selectcol_arrayref("SELECT DISTINCT name FROM test_case_categories WHERE product_id IN ($prod_ids)"); $products->{'environment'} = $dbh->selectcol_arrayref("SELECT DISTINCT name FROM test_environments WHERE product_id IN ($prod_ids)"); # This list must match the name of the select fields and the names above $products->{'selectTypes'} = [qw{version milestone component build category environment}]; my $json = new JSON; $json->autoconv(0); print $json->objToJson($products); } elsif ($action eq 'get_products'){ my @prod; if (Bugzilla->params->{'useclassification'}){ my @classes = $cgi->param('class_ids'); foreach my $id (@classes){ my $class = Bugzilla::Testopia::Classification->new($id); push @prod, @{$class->user_visible_products}; } } else { @prod = Bugzilla->user->get_selectable_products; } my $ret; foreach my $e (@prod){ $ret .= $e->{'id'}.'||'.$e->{'name'}.'|||'; } chop($ret); print $ret; } elsif ($action eq 'get_categories'){ my @prod_ids = $cgi->param('prod_id'); my $ret; foreach my $prod_id (@prod_ids){ detaint_natural($prod_id); my $cat = Bugzilla::Testopia::Environment::Category->new({}); my $cats_ref = $cat->get_element_categories_by_product($prod_id); foreach my $e (@{$cats_ref}){ $ret .= $e->id.'||'.$e->name.'|||'; } } chop($ret); print $ret; } elsif ($action eq 'get_elements'){ my @cat_ids = $cgi->param('cat_id'); my $ret; my @elmnts; foreach my $cat_id (@cat_ids){ detaint_natural($cat_id); my $cat = Bugzilla::Testopia::Environment::Category->new($cat_id); my $elmnts_ref = $cat->get_elements_by_category($cat->{'name'}); foreach my $e (@{$elmnts_ref}){ push @elmnts, Bugzilla::Testopia::Environment::Element->new($e->{'element_id'}); } } foreach my $e (@elmnts){ $ret .= $e->id.'||'.$e->name.'|||'; } chop($ret); print $ret; } elsif ($action eq 'get_properties'){ my @elmnt_ids = $cgi->param('elmnt_id'); my $ret; foreach my $elmnt_id (@elmnt_ids){ detaint_natural($elmnt_id); my $elmnt = Bugzilla::Testopia::Environment::Element->new($elmnt_id); my $props = $elmnt->get_properties(); foreach my $e (@{$props}){ $ret .= $e->id.'||'.$e->name.'|||'; } } chop($ret); print $ret; } elsif ($action eq 'get_valid_exp'){ my @prop_ids = $cgi->param('prop_id'); my $ret; foreach my $prop_id (@prop_ids){ detaint_natural($prop_id); my $prop = Bugzilla::Testopia::Environment::Property->new($prop_id); my $exp = $prop->validexp; my @exps = split /\|/, $exp; foreach my $exp (@exps){ $ret .=$exp.'|||'; } } chop($ret); print $ret; } elsif ($action eq 'save_query'){ my $query = $cgi->param('query_part'); my $qname = $cgi->param('query_name'); ThrowUserError('query_name_missing') unless $qname; trick_taint($query); trick_taint($qname); my ($name) = $dbh->selectrow_array( "SELECT name FROM test_named_queries WHERE userid = ? AND name = ?", undef,(Bugzilla->user->id, $qname)); if ($name){ $dbh->do( "UPDATE test_named_queries SET query = ? WHERE userid = ? AND name = ?", undef,($query, Bugzilla->user->id, $qname)); $vars->{'tr_message'} = "Updated saved search '$qname'"; } else{ my $quoted_qname = url_quote($qname); $query .= "&qname=$quoted_qname"; $dbh->do("INSERT INTO test_named_queries VALUES(?,?,?,?)", undef, (Bugzilla->user->id, $qname, 1, $query)); $vars->{'tr_message'} = "Search saved as '$qname'"; } display(); } elsif ($action eq 'delete_query'){ my $qname = $cgi->param('query_name'); trick_taint($qname); $dbh->do("DELETE FROM test_named_queries WHERE userid = ? AND name = ?", undef, (Bugzilla->user->id, $qname)); $vars->{'tr_message'} = "Testopia Saved Search '$qname' Deleted"; display(); } else{ display(); } sub display { #TODO: Support default query my $tab = $cgi->param('current_tab') || ''; if ($tab eq 'plan'){ $vars->{'plan'} = Bugzilla::Testopia::TestPlan->new({}); $vars->{'title'} = "Search For Test Plans"; $vars->{'versions'} = get_searchable_objects('versions'); } elsif ($tab eq 'run'){ $vars->{'title'} = "Search For Test Runs"; $vars->{'run'} = Bugzilla::Testopia::TestRun->new({});; $vars->{'versions'} = get_searchable_objects('versions'); $vars->{'milestones'} = get_searchable_objects('milestones'); $vars->{'builds'} = get_searchable_objects('builds'); $vars->{'environments'} = get_searchable_objects('environments'); } elsif ($tab eq 'environment'){ $vars->{'title'} = "Search For Test Run Environments"; $vars->{'classifications'} = Bugzilla->user->get_selectable_classifications; $vars->{'products'} = Bugzilla->user->get_selectable_products; $vars->{'env'} = Bugzilla::Testopia::Environment->new({}); } elsif ($tab eq 'case_run'){ $vars->{'title'} = "Search For Test Case-Runs"; $vars->{'case'} = Bugzilla::Testopia::TestCase->new({}); $vars->{'run'} = Bugzilla::Testopia::TestRun->new({}); $vars->{'caserun'} = Bugzilla::Testopia::TestCaseRun->new({}); $vars->{'versions'} = get_searchable_objects('versions'); $vars->{'milestones'} = get_searchable_objects('milestones'); $vars->{'builds'} = get_searchable_objects('builds'); $vars->{'environments'} = get_searchable_objects('environments'); $vars->{'components'} = get_searchable_objects('components'); $vars->{'categories'} = get_searchable_objects('categories'); } else { # show the case form $tab = 'case'; my $case = Bugzilla::Testopia::TestCase->new({ 'case_id' => 0 }); $vars->{'title'} = "Search For Test Cases"; $vars->{'case'} = $case; $vars->{'components'} = get_searchable_objects('components'); $vars->{'categories'} = get_searchable_objects('categories'); } $vars->{'report'} = $cgi->param('report'); $vars->{'current_tab'} = $tab; $template->process("testopia/search/advanced.html.tmpl", $vars) || ThrowTemplateError($template->error()); }