#!/usr/bin/perl -w # -*- 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 Testopia System. # # 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): Greg Hendricks # Al Rodriguez package OBJ_TestCase; use lib '.'; use lib '../..'; use strict; use base qw(Test::Unit::TestCase); use Bugzilla; use Bugzilla::Constants; use Testopia::TestCase; use Testopia::TestPlan; use Testopia::TestTag; use Testopia::TestCaseRun; use Test; use Bugzilla::Extension::Testopia::Test::Util; use Bugzilla::Extension::Testopia::Test::Constants; use Test::Exception; use Test::Deep; use Test::More; Bugzilla->error_mode(ERROR_MODE_DIE); use constant DB_TABLE => 'test_cases'; use constant ID_FIELD => 'case_id'; our $dbh = Bugzilla->dbh; our $obj = Test::test_init(DB_TABLE, ID_FIELD, 'Testopia::TestCase'); sub test_init{ #$obj = Test::test_init(DB_TABLE, ID_FIELD, 'Testopia::TestCase'); } sub check_alias{ my $id = $dbh->selectrow_array("SELECT MAX(case_id) FROM test_cases WHERE case_id <> ?", undef, $obj->id); $dbh->do("UPDATE test_cases SET alias = 'TEST' WHERE case_id = $id"); dies_ok(sub{$obj->_check_alias('TEST')}, 'Alias Must be Unique'); ok($obj->_check_alias('UNIQUE ALIAS'), 'Alias is Unique'); } sub check_arguments{ # _check_arguments returns the arguments and does no checking ok($obj->_check_arguments('-a', 'something', 'something else'), 'Arguments Passed'); } sub check_dependency{ dies_ok(sub{$obj->_check_dependency('DIE')}, 'Unused Alias'); dies_ok(sub{$obj->_check_dependency(50)}, 'Invalid Case ID'); ok($obj->_check_dependency($obj->id), 'Valid Id'); } sub check_bugs{ my $creds = Bugzilla::Extension::Testopia::Test::Constants->LOGIN_CREDENTIALS; foreach (Testopia::Test::Constants->LOGIN_TYPES){ my $login = $creds->{$_}; Test::set_user($login->{'id'}, $login->{'login_name'}, $login->{'password'}); # If the user does not have rights to view the bug, this should die unless(Bugzilla->user->can_see_bug(2) ){ dies_ok(sub{$obj->_check_bugs(2, 'bugs')}, "User " . Bugzilla->user->{'login_name'} ." does not have rights to view bugs") } else{ ok( defined $obj->_check_bugs(2, 'bugs'), "User" . Bugzilla->user->{'login_name'} . " Can see bug 2"); } } dies_ok( sub{$obj->_check_bugs(90, 'bugs')}, "Bug with ID 90 does not exist"); } sub check_status{ dies_ok(sub{$obj->_check_status(999)}, 'Test Case Status Does Not Exist'); ok($obj->_check_status(1), 'Test Case Status 1 Exists'); } sub check_components{ dies_ok(sub{$obj->_check_components}, 'Missing Parameter Components'); ok($obj->_check_components(1), 'Valid Component'); } sub check_tester{ my $creds = Bugzilla::Extension::Testopia::Test::Constants->LOGIN_CREDENTIALS; foreach (Testopia::Test::Constants->LOGIN_TYPES){ my $login = $creds->{$_}; ok($obj->_check_tester($login->{'login_name'}), 'User '. $login->{'login_name'} .' has a valid Login'); } } sub check_time{ dies_ok(sub{$obj->_check_time('2 Hours')}, 'Invalid Time Format'); dies_ok(sub{$obj->_check_time('1:2:3:4')}, 'Invalid Time Format'); dies_ok(sub{$obj->_check_time('2 Hours')}, 'Invalid Time Format'); ok($obj->_check_time eq 0, 'Time Value is Required'); } sub check_automated{ dies_ok(sub{$obj->_check_automated('INVALID')}, 'Invalid Automated Value'); dies_ok(sub{$obj->_check_automated(undef)}, 'undef Not Valid Automated Value'); ok($obj->_check_automated(1) eq 1, '1 is Valid Value'); ok($obj->_check_automated(0) eq 0, '0 is Valid Value'); } sub check_sortkey{ dies_ok(sub{$obj->_check_automated('INVALID')}, 'Invalid Sort Key'); ok($obj->_check_automated(1), 'Valid Sort Key'); ok($obj->_check_automated(100000), 'Valid Sort Key'); } sub check_plans{ my $plan = new Testopia::TestPlan(1); # NOTE: The real method checks if the array is greater than 0, #Not if it actually holds Testopia::TestPlan objects dies_ok(sub{$obj->_check_plans}, 'Plans Array Must Not Be Empty'); dies_ok(sub{$obj->_check_plans(2)}, 'Plans Array Must Be An Array'); ok($obj->_check_plans([$plan]), 'Plans Array Not Undef'); } sub check_priority{ my $pri1 = $obj->_check_priority(1); my $pri2 = $obj->_check_priority('P1'); cmp_deeply($pri1, $pri2, 'Same Priority Found with Id and Value'); } sub check_runs{ dies_ok(sub{$obj->_check_runs(1000)}, 'Run ID Does Not Exist'); ok(defined $obj->_check_runs(1), 'Run Exists'); } sub check_summary{ dies_ok(sub{$obj->_check_summary()}, 'Summary Must Not Be undef'); dies_ok(sub{$obj->_check_summary('')}, 'Summary Must Not Be Empty'); ok($obj->_check_summary('SUMMARY') eq 'SUMMARY', 'Valid Summary'); } sub check_category{ my $plan = new Testopia::TestPlan(1); Testopia::TestCase->_check_category(1, $plan); } sub test_create{ check_alias; check_arguments; check_dependency; check_bugs; check_status; check_components; check_tester; check_time; check_automated; check_plans; check_priority; check_runs; check_sortkey; check_summary; check_category; Test::set_user('1', 'admin@testopia.com', 'admin@testopia.com'); my $plan = new Testopia::TestPlan(999); my $hash = { 'case_status_id' => 1, 'priority_id' => 999, 'default_tester_id' => 1, 'isautomated' => 1, 'sortkey' => 1, 'script' => 'SCRIPT', 'arguments' => 'ARGS', 'summary' => 'SUMMARY', 'requirement' => '', 'alias' => '', 'estimated_time' => '1:23:4', 'dependson' => '990', 'blocks' => '999', 'plans' => [$plan], 'runs' => '999', 'tags' => '', 'components' => '999', 'bugs' => '999', 'category_id' => 999, 'author_id' => 999}; my $creds = Bugzilla::Extension::Testopia::Test::Constants->LOGIN_CREDENTIALS; foreach (Testopia::Test::Constants->LOGIN_TYPES){ my $login = $creds->{$_}; Test::set_user($login->{'id'}, $login->{'login_name'}, $login->{'password'}); # If the user does not have rights to create a Test Case, this should die unless(Bugzilla->user->can_see_bug(999)){ dies_ok( sub {Testopia::TestCase->create($hash)}, "User " . Bugzilla->user->{'login_name'} ." does not have rights to create a Test Case"); } else{ my $created_obj = Testopiaj::TestCase->create($hash); foreach my $field ($created_obj){ delete $created_obj->{$field} unless( defined $hash->{$field}); } my $db_obj = new Bugzilla::Extension::Testopia::TestCase($created_obj->id); $db_obj->{'plans'} = $db_obj->plans; $db_obj->{'version'} = 1; cmp_deeply($created_obj, $db_obj, 'Created Object Matched in DB'); $dbh->do("DELETE FROM test_cases WHERE case_id = " . $created_obj->id); } } } sub test_update{ $obj->set_alias('SOME ALIAS'); $obj->set_isautomated('1'); delete $obj->{'plans'}; delete $obj->{'version'}; delete $obj->{'type'}; $obj->update; my $db_obj = new Bugzilla::Extension::Testopia::TestCase($obj->id); cmp_deeply($obj, $db_obj, 'Update TestCase'); } sub test_get_selectable_components{ my @components; push @components, {'id' => '0', 'name' => '--Please Select--'}; my @comp_ids; foreach my $comp (@{$obj->components}){ push @comp_ids, $comp->{'id'}; } my $ids = $dbh->selectrow_arrayref( "SELECT id FROM components WHERE product_id IN (?) AND id NOT IN (?) ORDER BY name", undef, join(",", @{$obj->get_product_ids}), join(",", @comp_ids)); foreach my $id (@$ids){ push @components, Bugzilla::Component->new($id); } ok( defined $obj->get_selectable_components, 'Selectable Components Match'); } sub test_get_category_list{ my @categories; my $cat_ids = $dbh->selectrow_arrayref("SELECT category_id FROM test_case_categories WHERE product_id IN (?)", undef, join(",", @{$obj->get_product_ids})); foreach my $id (@$cat_ids){ push @categories, Bugzilla::Extension::Testopia::Category->new($id); } ok($obj->get_category_list, 'Category List Match'); } sub test_get_product_ids{ my $id = $obj->id; my @array = [1]; ok($obj->get_product_ids, 'Product Ids Retrieved'); @array = []; $obj->{'case_id'} = 0; cmp_deeply($obj->get_product_ids, @array, 'Product Ids Match W/No Case_Id'); $obj->{'case_id'} = $id; } sub test_get_caserun_count{ my $id = $obj->{'case_id'}; $obj->{'case_id'} = 4; ok($obj->get_caserun_count eq 1, '1 Test Case Run Count'); ok($obj->get_caserun_count(1) eq 1, '1 Test Case Run Count W/Status ID'); $obj->{'case_id'} = $id; } sub test_add_tag{ my $tags = ['TEST1']; $obj->add_tag(@$tags); $obj->add_tag('TEST2', 'TEST2','TEST2','TEST3'); #Get Tags associated with this TestCase my $query = "SELECT tag_id FROM test_case_tags WHERE case_id = ?"; my $test_tags = $dbh->selectcol_arrayref($query, undef, $obj->id); for(@$test_tags){ my $tag = new Testopia::TestTag($_); ok(defined $tag, $tag->{'tag_name'} . " Tag Added Correctly"); } } sub test_remove_tag{ dies_ok(sub{$obj->remove_tag('FAKE_TAG')}, 'Cannot Remove Tag Not Already In DB'); my $tag = 'TEST'; $obj->add_tag($tag); $obj->remove_tag($tag); my $tag_id = $dbh->selectcol_arrayref("SELECT tag_id FROM test_tags WHERE tag_name = ?", undef, $tag); my $id = $dbh->selectcol_arrayref("SELECT tag_id FROM test_case_tags WHERE tag_id = ? and case_id = ?", undef, $tag_id->[0], $obj->id); ok( scalar @$id eq 0, 'Tag Removed Successfully'); } sub test_attach_bug{ my $creds = Bugzilla::Extension::Testopia::Test::Constants->LOGIN_CREDENTIALS; foreach (Testopia::Test::Constants->LOGIN_TYPES){ my $login = $creds->{$_}; Test::set_user($login->{'id'}, $login->{'login_name'}, $login->{'password'}); # If the user does not have rights to add a bug, this should die unless(Bugzilla->user->can_see_bug(1)){ dies_ok( sub {$obj->attach_bug(1)}, "User " . Bugzilla->user->{'login_name'} ." does not have rights to add bugs"); } else{ my $bugs = [1]; $obj->attach_bug($bugs, 1); my $attached_bugs = $dbh->selectrow_arrayref("SELECT bug_id FROM test_case_bugs WHERE bug_id in (?) AND case_id = ?", undef, (join ",", @$bugs), $obj->id); cmp_deeply($attached_bugs, $bugs, 'Bugs Added Correctly'); } } } sub test_detach_bug{ my $bug_ids = [1, 2]; $obj->attach_bug(1); $obj->attach_bug(2); my $query = "SELECT bug_id FROM test_case_bugs WHERE bug_id in (?)"; my $old_bugs = $dbh->selectrow_arrayref($query, undef, join (",", @$bug_ids)); $obj->detach_bug($bug_ids); my $new_bugs = $dbh->selectrow_arrayref($query, undef, join (",", @$bug_ids)); ok( $old_bugs && ! defined $new_bugs, "Bugs Detached" ); } sub test_add_component{ my $comps = [1]; my $query = "SELECT component_id FROM test_case_components WHERE case_id = ?"; my $delete = "DELETE FROM test_case_components WHERE case_id = ". $obj->{'case_id'}; $obj->add_component($comps); my @db_comps = $dbh->selectrow_arrayref($query, undef, $obj->id); cmp_deeply($comps, @db_comps, "Components added correctly"); $dbh->do($delete); $obj->add_component($comps, 1); @db_comps = $dbh->selectrow_arrayref($query, undef, $obj->id); cmp_deeply($comps, @db_comps, "Components added correctly"); $dbh->do($delete); } sub test_remove_component{ my $comp = 1; my $query = "SELECT component_id FROM test_case_components WHERE case_id = ?"; $obj->add_component($comp); my $db_comps = $dbh->selectcol_arrayref($query, undef, $comp); $obj->remove_component($comp); my $new_db_comps = $dbh->selectcol_arrayref($query, undef, $comp); ok( $new_db_comps ne $db_comps, 'Components Removed'); } sub test_add_to_run{ my $run = 1; my $before_adding = $dbh->selectrow_hashref("SELECT case_run_id, run_id, case_id, case_run_status_id, case_text_version, build_id, iscurrent, environment_id FROM test_case_runs WHERE run_id = $run"); $obj->add_to_run($run); my $db_obj = $dbh->selectrow_hashref("SELECT * FROM test_case_runs WHERE run_id = $run"); my $object = new Bugzilla::Extension::Testopia::TestCaseRun($db_obj->{'case_run_id'}); cmp_deeply($db_obj, noclass($object), 'Test Case Added to Run'); } sub test_add_blocks{ my $blocks = 2; $obj->add_blocks($blocks); my $dep = $dbh->selectrow_arrayref("SELECT blocked FROM test_case_dependencies WHERE dependson = ?", undef, $obj->id); ok ( defined $dep , "Block Added"); _remove_blocks(); } sub _remove_blocks{ my $block = 2; my $id = $dbh->selectrow_array("SELECT MAX(blocked) FROM test_case_dependencies"); my $query = "SELECT blocked FROM test_case_dependencies WHERE dependson = ?"; my $db_deps = $dbh->selectrow_arrayref($query, undef, $obj->id); $obj->remove_blocks($block); my $new_db_deps = $dbh->selectrow_arrayref($query, undef, $obj->id); ok($db_deps ne $new_db_deps, 'Block Removed'); } sub test_add_dependson{ dies_ok ( sub{$obj->add_dependson($obj->id)}, "Cannot Be Dependant on Self"); $obj->add_dependson(10); my $dep = $dbh->selectcol_arrayref("SELECT dependson FROM test_case_dependencies WHERE blocked = ?", undef, $obj->id); ok ( $dep->[0] eq 10, "Dependency Added"); _remove_dependson(); } sub _remove_dependson{ my $id = $dbh->selectrow_array("SELECT MAX(dependson) FROM test_case_dependencies"); my $query = "SELECT dependson FROM test_case_dependencies WHERE dependson = ?"; my $db_deps = $dbh->selectcol_arrayref($query, undef, $id); $obj->remove_dependson($id); my $new_db_deps = $dbh->selectcol_arrayref($query, undef, $id); ok(@$db_deps ne @$new_db_deps, 'Dependency Removed'); } sub test_compare_doc_versions{ my $same = { 'breakdown' => '', 'setup' => '', 'effect' => '', 'action' => '' }; my $id = $dbh->selectrow_array("SELECT MAX(plan_id) FROM test_plans ", undef); cmp_deeply($obj->compare_doc_versions($obj->id, $obj->id), $same, 'Same Documents'); $dbh->do("DELETE FROM test_case_texts WHERE case_id = $id"); $obj->store_text($id, $obj->id, 'ACTION2', 'EFFECT', 'SETUP', 'BREAKDOWN'); ok($obj->compare_doc_versions($obj->id, $id) ne $same, 'Different Documents'); } sub test_diff_case_doc{ my $vals = $dbh->selectcol_arrayref("SELECT action, effect, setup, breakdown FROM test_case_texts WHERE case_id = ?", undef, $obj->id); ok($obj->diff_case_doc('ACTION1', $vals->[1], $vals->[2], $vals->[3]), 'Case Docs are Different'); delete $obj->{'version'}; } sub test_store_text{ my $dbh = Bugzilla->dbh; my $text = { 'breakdown' => 'BREAKDOWN', 'setup' => 'SETUP', 'case_text_version' => '1', 'who' => '999', 'effect' => 'EFFECT', 'action' => 'ACTION', 'creation_ts' => '2008-06-04 14:57:00', 'case_id' => '999' }; ok($obj->store_text('999', '999', 'ACTION', 'EFFECT', 'SETUP', 'BREAKDOWN', 1, '2008-06-04 14:57:00') eq 1, 'Version Updated'); my $db_text = $dbh->selectrow_hashref('SELECT * FROM test_case_texts WHERE case_id = 999'); cmp_deeply($text, $db_text, 'Text Stored Correctly'); } sub test_link_plan{ my $id = $obj->id; $obj->link_plan(1, $id); my $db_plan = $dbh->selectrow_hashref("SELECT * FROM test_case_plans WHERE case_id = $id AND plan_id = 1"); my $known_plan = {'case_id' => $id, 'plan_id' => '1'}; cmp_deeply($db_plan, $known_plan, 'Plan Linked To Test Case'); } sub _unlink_plan{ my $id = $obj->id; my $max_id = $dbh->selectrow_array("SELECT MAX(plan_id) FROM test_plans ", undef); $obj->link_plan($max_id, $id); $obj->link_plan($max_id-1, $id); my $query = "SELECT * FROM test_case_plans WHERE case_id = $id AND plan_id = 1"; my $old_db_plan = $dbh->selectrow_hashref($query); $obj->unlink_plan($max_id); my $new_db_plan = $dbh->selectrow_hashref($query); ok(defined $old_db_plan && !defined $new_db_plan, 'Plan Unlinked'); } sub test_copy{ my $copy_id = $obj->copy($obj->{'author_id'}, $obj->{'default_tester_id'}, 0); my $copy = { 'case_id' => $copy_id, 'case_status_id' => $obj->{'case_status_id'}, 'category_id' => $obj->{'category_id'}, 'priority_id' => $obj->{'priority_id'}, 'author_id' => $obj->{'author_id'}, 'default_tester_id' => $obj->{'default_tester_id'}, 'estimated_time' => $obj->{'estimated_time'}, 'isautomated' => $obj->{'isautomated'}, 'sortkey' => $obj->sortkey, 'script' => $obj->{'script'}, 'arguments' => $obj->{'arguments'}, 'summary' => $obj->{'summary'}, 'requirement' => $obj->{'requirement'}}; my $db_copy = $dbh->selectrow_hashref("SELECT * FROM test_cases WHERE case_id = ?", undef, $copy_id); delete $db_copy->{'creation_date'}; delete $db_copy->{'alias'}; delete $db_copy->{'version'}; cmp_deeply($db_copy, $copy, 'Copy Created Successfully'); } sub test_class_check_alias{ my $no = $obj->class_check_alias('FAKE'); ok( ! defined $no, 'Alias not in DB'); } sub test_history{ ok(defined $obj->history, "History Exists"); } sub test_obliterate{ my $id = $dbh->selectrow_array("SELECT MAX(case_id) FROM test_cases WHERE case_id <> ?", undef, $obj->id); my $dead_obj = new Testopia::TestCase($id); $dead_obj->obliterate;use base qw(Exporter Test::Unit::TestCase); my $db_dead = $dbh->selectrow_arrayref("SELECT * FROM test_cases WHERE case_id = ?", undef, $id); ok( !defined $db_dead, 'Test Case Deleted'); } sub new { my $self = shift()->SUPER::new(@_); return $self; } sub set_up { my $self = shift; } sub tear_down { my $self = shift; } 1;