diff options
author | Perl Tidy <perltidy@bugzilla.org> | 2018-12-05 21:38:52 +0100 |
---|---|---|
committer | Dylan William Hardison <dylan@hardison.net> | 2018-12-05 23:49:08 +0100 |
commit | 8ec8da0491ad89604700b3e29a227966f6d84ba1 (patch) | |
tree | 9d270f173330ca19700e0ba9f2ee931300646de1 /qa/t/lib | |
parent | a7bb5a65b71644d9efce5fed783ed545b9336548 (diff) | |
download | bugzilla-8ec8da0491ad89604700b3e29a227966f6d84ba1.tar.gz bugzilla-8ec8da0491ad89604700b3e29a227966f6d84ba1.tar.xz |
no bug - reformat all the code using the new perltidy rules
Diffstat (limited to 'qa/t/lib')
-rw-r--r-- | qa/t/lib/QA/REST.pm | 61 | ||||
-rw-r--r-- | qa/t/lib/QA/RPC.pm | 454 | ||||
-rw-r--r-- | qa/t/lib/QA/RPC/JSONRPC.pm | 192 | ||||
-rw-r--r-- | qa/t/lib/QA/RPC/XMLRPC.pm | 2 | ||||
-rw-r--r-- | qa/t/lib/QA/Tests.pm | 114 | ||||
-rw-r--r-- | qa/t/lib/QA/Util.pm | 593 |
6 files changed, 746 insertions, 670 deletions
diff --git a/qa/t/lib/QA/REST.pm b/qa/t/lib/QA/REST.pm index f900cc352..3d37e2277 100644 --- a/qa/t/lib/QA/REST.pm +++ b/qa/t/lib/QA/REST.pm @@ -19,43 +19,46 @@ use QA::Util; use parent qw(LWP::UserAgent Exporter); @QA::REST::EXPORT = qw( - MUST_FAIL - get_rest_client + MUST_FAIL + get_rest_client ); use constant MUST_FAIL => 1; sub get_rest_client { - my $rest_client = LWP::UserAgent->new( ssl_opts => { verify_hostname => 0 } ); - bless($rest_client, 'QA::REST'); - my $config = $rest_client->{bz_config} = get_config(); - $rest_client->{bz_url} = $config->{browser_url} . '/' . $config->{bugzilla_installation} . '/rest/'; - $rest_client->{bz_default_headers} = {'Accept' => 'application/json', 'Content-Type' => 'application/json'}; - return $rest_client; + my $rest_client = LWP::UserAgent->new(ssl_opts => {verify_hostname => 0}); + bless($rest_client, 'QA::REST'); + my $config = $rest_client->{bz_config} = get_config(); + $rest_client->{bz_url} + = $config->{browser_url} . '/' . $config->{bugzilla_installation} . '/rest/'; + $rest_client->{bz_default_headers} + = {'Accept' => 'application/json', 'Content-Type' => 'application/json'}; + return $rest_client; } sub bz_config { return $_[0]->{bz_config}; } sub call { - my ($self, $method, $data, $http_verb, $expect_to_fail) = @_; - $http_verb = lc($http_verb || 'GET'); - $data //= {}; - - my %args = %{ $self->{bz_default_headers} }; - # We do not pass the API key in the URL, so that it's not logged by the web server. - if ($http_verb eq 'get' && $data->{api_key}) { - $args{'X-BUGZILLA-API-KEY'} = $data->{api_key}; - } - elsif ($http_verb ne 'get') { - $args{Content} = encode_json($data); - } - - my $response = $self->$http_verb($self->{bz_url} . $method, %args); - my $res = decode_json($response->decoded_content); - if ($response->is_success xor $expect_to_fail) { - return $res; - } - else { - die 'error ' . $res->{code} . ': ' . $res->{message} . "\n"; - } + my ($self, $method, $data, $http_verb, $expect_to_fail) = @_; + $http_verb = lc($http_verb || 'GET'); + $data //= {}; + + my %args = %{$self->{bz_default_headers}}; + +# We do not pass the API key in the URL, so that it's not logged by the web server. + if ($http_verb eq 'get' && $data->{api_key}) { + $args{'X-BUGZILLA-API-KEY'} = $data->{api_key}; + } + elsif ($http_verb ne 'get') { + $args{Content} = encode_json($data); + } + + my $response = $self->$http_verb($self->{bz_url} . $method, %args); + my $res = decode_json($response->decoded_content); + if ($response->is_success xor $expect_to_fail) { + return $res; + } + else { + die 'error ' . $res->{code} . ': ' . $res->{message} . "\n"; + } } diff --git a/qa/t/lib/QA/RPC.pm b/qa/t/lib/QA/RPC.pm index 4053c4dfe..f1b44eea8 100644 --- a/qa/t/lib/QA/RPC.pm +++ b/qa/t/lib/QA/RPC.pm @@ -16,9 +16,9 @@ use Storable qw(dclone); use Test::More; sub bz_config { - my $self = shift; - $self->{bz_config} ||= QA::Util::get_config(); - return $self->{bz_config}; + my $self = shift; + $self->{bz_config} ||= QA::Util::get_config(); + return $self->{bz_config}; } # True if we're doing calls over GET instead of POST. @@ -29,12 +29,12 @@ sub bz_get_mode { return 0 } # and Bugzilla_password with every future call until User.logout is called # (which actually just calls _bz_clear_credentials, under GET). sub _bz_credentials { - my ($self, $user, $pass) = @_; - if (@_ == 3) { - $self->{_bz_credentials}->{user} = $user; - $self->{_bz_credentials}->{pass} = $pass; - } - return $self->{_bz_credentials}; + my ($self, $user, $pass) = @_; + if (@_ == 3) { + $self->{_bz_credentials}->{user} = $user; + $self->{_bz_credentials}->{pass} = $pass; + } + return $self->{_bz_credentials}; } sub _bz_clear_credentials { delete $_[0]->{_bz_credentials} } @@ -43,240 +43,258 @@ sub _bz_clear_credentials { delete $_[0]->{_bz_credentials} } ################################ sub bz_log_in { - my ($self, $user) = @_; - my $username = $self->bz_config->{"${user}_user_login"}; - my $password = $self->bz_config->{"${user}_user_passwd"}; - - if ($self->bz_get_mode) { - $self->_bz_credentials($username, $password); - return; - } - - my $call = $self->bz_call_success( - 'User.login', { login => $username, password => $password }); - cmp_ok($call->result->{id}, 'gt', 0, $self->TYPE . ": Logged in as $user"); - $self->{_bz_credentials}->{token} = $call->result->{token}; + my ($self, $user) = @_; + my $username = $self->bz_config->{"${user}_user_login"}; + my $password = $self->bz_config->{"${user}_user_passwd"}; + + if ($self->bz_get_mode) { + $self->_bz_credentials($username, $password); + return; + } + + my $call = $self->bz_call_success('User.login', + {login => $username, password => $password}); + cmp_ok($call->result->{id}, 'gt', 0, $self->TYPE . ": Logged in as $user"); + $self->{_bz_credentials}->{token} = $call->result->{token}; } sub bz_call_success { - my ($self, $method, $orig_args, $test_name) = @_; - my $args = $orig_args ? dclone($orig_args) : {}; - - if ($self->bz_get_mode and $method eq 'User.logout') { - $self->_bz_clear_credentials(); - return; - } - - my $call; - # Under XMLRPC::Lite, if we pass undef as the second argument, - # it sends a single param <value />, which shows up as an - # empty string on the Bugzilla side. - if ($self->{_bz_credentials}->{token}) { - $args->{Bugzilla_token} = $self->{_bz_credentials}->{token}; - } - - if (scalar keys %$args) { - $call = $self->call($method, $args); - } - else { - $call = $self->call($method); - } - $test_name ||= "$method returned successfully"; - $self->_handle_undef_response($test_name) if !$call; - ok(!$call->fault, $self->TYPE . ": $test_name") - or diag($call->faultstring); - - if ($method eq 'User.logout') { - delete $self->{_bz_credentials}->{token}; - } - return $call; + my ($self, $method, $orig_args, $test_name) = @_; + my $args = $orig_args ? dclone($orig_args) : {}; + + if ($self->bz_get_mode and $method eq 'User.logout') { + $self->_bz_clear_credentials(); + return; + } + + my $call; + + # Under XMLRPC::Lite, if we pass undef as the second argument, + # it sends a single param <value />, which shows up as an + # empty string on the Bugzilla side. + if ($self->{_bz_credentials}->{token}) { + $args->{Bugzilla_token} = $self->{_bz_credentials}->{token}; + } + + if (scalar keys %$args) { + $call = $self->call($method, $args); + } + else { + $call = $self->call($method); + } + $test_name ||= "$method returned successfully"; + $self->_handle_undef_response($test_name) if !$call; + ok(!$call->fault, $self->TYPE . ": $test_name") or diag($call->faultstring); + + if ($method eq 'User.logout') { + delete $self->{_bz_credentials}->{token}; + } + return $call; } sub bz_call_fail { - my ($self, $method, $orig_args, $faultstring, $test_name) = @_; - my $args = $orig_args ? dclone($orig_args) : {}; - - if ($self->{_bz_credentials}->{token}) { - $args->{Bugzilla_token} = $self->{_bz_credentials}->{token}; - } - - $test_name ||= "$method failed (as intended)"; - my $call = $self->call($method, $args); - $self->_handle_undef_response($test_name) if !$call; - ok($call->fault, $self->TYPE . ": $test_name") - or diag("Returned: " . Dumper($call->result)); - if (defined $faultstring) { - cmp_ok(trim($call->faultstring), '=~', $faultstring, - $self->TYPE . ": Got correct fault for $method"); - } - ok($call->faultcode - && (($call->faultcode < 32000 && $call->faultcode > -32000) - # Fault codes 32610 and above are OK because they are errors - # that we expect and test for sometimes. - || $call->faultcode >= 32610), - $self->TYPE . ': Fault code is set properly') - or diag("Code: " . $call->faultcode - . " Message: " . $call->faultstring); - - return $call; + my ($self, $method, $orig_args, $faultstring, $test_name) = @_; + my $args = $orig_args ? dclone($orig_args) : {}; + + if ($self->{_bz_credentials}->{token}) { + $args->{Bugzilla_token} = $self->{_bz_credentials}->{token}; + } + + $test_name ||= "$method failed (as intended)"; + my $call = $self->call($method, $args); + $self->_handle_undef_response($test_name) if !$call; + ok($call->fault, $self->TYPE . ": $test_name") + or diag("Returned: " . Dumper($call->result)); + if (defined $faultstring) { + cmp_ok(trim($call->faultstring), + '=~', $faultstring, $self->TYPE . ": Got correct fault for $method"); + } + ok( + $call->faultcode && ( + ($call->faultcode < 32000 && $call->faultcode > -32000) + + # Fault codes 32610 and above are OK because they are errors + # that we expect and test for sometimes. + || $call->faultcode >= 32610 + ), + $self->TYPE . ': Fault code is set properly' + ) or diag("Code: " . $call->faultcode . " Message: " . $call->faultstring); + + return $call; } sub _handle_undef_response { - my ($self, $test_name) = @_; - my $response = $self->transport->http_response; - die "$test_name:\n", $response->as_string; + my ($self, $test_name) = @_; + my $response = $self->transport->http_response; + die "$test_name:\n", $response->as_string; } sub bz_get_products { - my ($self) = @_; - $self->bz_log_in('QA_Selenium_TEST'); - - my $accessible = $self->bz_call_success('Product.get_accessible_products'); - my $prod_call = $self->bz_call_success('Product.get', $accessible->result); - my %products; - foreach my $prod (@{ $prod_call->result->{products} }) { - $products{$prod->{name}} = $prod->{id}; - } - - $self->bz_call_success('User.logout'); - return \%products; + my ($self) = @_; + $self->bz_log_in('QA_Selenium_TEST'); + + my $accessible = $self->bz_call_success('Product.get_accessible_products'); + my $prod_call = $self->bz_call_success('Product.get', $accessible->result); + my %products; + foreach my $prod (@{$prod_call->result->{products}}) { + $products{$prod->{name}} = $prod->{id}; + } + + $self->bz_call_success('User.logout'); + return \%products; } -sub _string_array { map { random_string() } (1..$_[0]) } +sub _string_array { + map { random_string() } (1 .. $_[0]); +} sub bz_create_test_bugs { - my ($self, $second_private) = @_; - my $config = $self->bz_config; - - my @whiteboard_strings = _string_array(3); - my @summary_strings = _string_array(3); - - my $public_bug = create_bug_fields($config); - $public_bug->{alias} = random_string(40); - $public_bug->{whiteboard} = join(' ', @whiteboard_strings); - $public_bug->{summary} = join(' ', @summary_strings); - - my $private_bug = dclone($public_bug); - $private_bug->{alias} = random_string(40); - if ($second_private) { - $private_bug->{product} = 'QA-Selenium-TEST'; - $private_bug->{component} = 'QA-Selenium-TEST'; - $private_bug->{target_milestone} = 'QAMilestone'; - $private_bug->{version} = 'QAVersion'; - # Although we don't directly use this, this helps some tests that - # depend on the values in $private_bug. - $private_bug->{creator} = $config->{PRIVATE_BUG_USER . '_user_login'}; - } - - my @create_bugs = ( - { user => 'editbugs', - args => $public_bug, - test => 'Create a public bug' }, - { user => $second_private ? PRIVATE_BUG_USER : 'editbugs', - args => $private_bug, - test => $second_private ? 'Create a private bug' - : 'Create a second public bug' }, - ); - - my $post_success = sub { - my ($call, $t) = @_; - my $id = $call->result->{id}; - $t->{args}->{id} = $id; - }; - - # Creating the bugs isn't really a test, it's just preliminary work - # for the tests. So we just run it with one of the RPC clients. - $self->bz_run_tests(tests => \@create_bugs, method => 'Bug.create', - post_success => $post_success); - - return ($public_bug, $private_bug); + my ($self, $second_private) = @_; + my $config = $self->bz_config; + + my @whiteboard_strings = _string_array(3); + my @summary_strings = _string_array(3); + + my $public_bug = create_bug_fields($config); + $public_bug->{alias} = random_string(40); + $public_bug->{whiteboard} = join(' ', @whiteboard_strings); + $public_bug->{summary} = join(' ', @summary_strings); + + my $private_bug = dclone($public_bug); + $private_bug->{alias} = random_string(40); + if ($second_private) { + $private_bug->{product} = 'QA-Selenium-TEST'; + $private_bug->{component} = 'QA-Selenium-TEST'; + $private_bug->{target_milestone} = 'QAMilestone'; + $private_bug->{version} = 'QAVersion'; + + # Although we don't directly use this, this helps some tests that + # depend on the values in $private_bug. + $private_bug->{creator} = $config->{PRIVATE_BUG_USER . '_user_login'}; + } + + my @create_bugs = ( + {user => 'editbugs', args => $public_bug, test => 'Create a public bug'}, + { + user => $second_private ? PRIVATE_BUG_USER : 'editbugs', + args => $private_bug, + test => $second_private ? 'Create a private bug' : 'Create a second public bug' + }, + ); + + my $post_success = sub { + my ($call, $t) = @_; + my $id = $call->result->{id}; + $t->{args}->{id} = $id; + }; + + # Creating the bugs isn't really a test, it's just preliminary work + # for the tests. So we just run it with one of the RPC clients. + $self->bz_run_tests( + tests => \@create_bugs, + method => 'Bug.create', + post_success => $post_success + ); + + return ($public_bug, $private_bug); } sub bz_run_tests { - my ($self, %params) = @_; - # Required params - my $config = $self->bz_config; - my $tests = $params{tests}; - my $method = $params{method}; - - # Optional params - my $post_success = $params{post_success}; - my $pre_call = $params{pre_call}; - - my $former_user = ''; - foreach my $t (@$tests) { - # Only logout/login if the user has changed since the last test - # (this saves us LOTS of needless logins). - my $user = $t->{user} || ''; - if ($former_user ne $user) { - $self->bz_call_success('User.logout') if $former_user; - $self->bz_log_in($user) if $user; - $former_user = $user; - } - - $pre_call->($t, $self) if $pre_call; - - if ($t->{error}) { - $self->bz_call_fail($method, $t->{args}, $t->{error}, $t->{test}); - } - else { - my $call = $self->bz_call_success($method, $t->{args}, $t->{test}); - if ($call->result && $post_success) { - $post_success->($call, $t, $self); - } - } + my ($self, %params) = @_; + + # Required params + my $config = $self->bz_config; + my $tests = $params{tests}; + my $method = $params{method}; + + # Optional params + my $post_success = $params{post_success}; + my $pre_call = $params{pre_call}; + + my $former_user = ''; + foreach my $t (@$tests) { + + # Only logout/login if the user has changed since the last test + # (this saves us LOTS of needless logins). + my $user = $t->{user} || ''; + if ($former_user ne $user) { + $self->bz_call_success('User.logout') if $former_user; + $self->bz_log_in($user) if $user; + $former_user = $user; + } + + $pre_call->($t, $self) if $pre_call; + + if ($t->{error}) { + $self->bz_call_fail($method, $t->{args}, $t->{error}, $t->{test}); + } + else { + my $call = $self->bz_call_success($method, $t->{args}, $t->{test}); + if ($call->result && $post_success) { + $post_success->($call, $t, $self); + } } + } - $self->bz_call_success('User.logout') if $former_user; + $self->bz_call_success('User.logout') if $former_user; } sub bz_test_bug { - my ($self, $fields, $bug, $expect, $t, $creation_time) = @_; - - foreach my $field (sort @$fields) { - # "description" is used by Bug.create but comments are not returned - # by Bug.get or Bug.search. - next if $field eq 'description'; - - my @include = @{ $t->{args}->{include_fields} || [] }; - my @exclude = @{ $t->{args}->{exclude_fields} || [] }; - if ( (@include and !grep($_ eq $field, @include)) - or (@exclude and grep($_ eq $field, @exclude)) ) - { - ok(!exists $bug->{$field}, "$field is not included") - or diag Dumper($bug); - next; - } - - if ($field =~ /^is_/) { - ok(defined $bug->{$field}, $self->TYPE . ": $field is not null"); - is($bug->{$field} ? 1 : 0, $expect->{$field} ? 1 : 0, - $self->TYPE . ": $field has the right boolean value"); - } - elsif ($field eq 'cc') { - foreach my $cc_item (@{ $expect->{cc} || [] }) { - ok(grep($_ eq $cc_item, @{ $bug->{cc} }), - $self->TYPE . ": $field contains $cc_item"); - } - } - elsif ($field eq 'creation_time' or $field eq 'last_change_time') { - my $creation_day; - # XML-RPC and JSON-RPC have different date formats. - if ($self->isa('QA::RPC::XMLRPC')) { - $creation_day = $creation_time->ymd(''); - } - else { - $creation_day = $creation_time->ymd; - } - - like($bug->{$field}, qr/^\Q${creation_day}\ET\d\d:\d\d:\d\d/, - $self->TYPE . ": $field has the right format"); - } - else { - is_deeply($bug->{$field}, $expect->{$field}, - $self->TYPE . ": $field value is correct"); - } + my ($self, $fields, $bug, $expect, $t, $creation_time) = @_; + + foreach my $field (sort @$fields) { + + # "description" is used by Bug.create but comments are not returned + # by Bug.get or Bug.search. + next if $field eq 'description'; + + my @include = @{$t->{args}->{include_fields} || []}; + my @exclude = @{$t->{args}->{exclude_fields} || []}; + if ( (@include and !grep($_ eq $field, @include)) + or (@exclude and grep($_ eq $field, @exclude))) + { + ok(!exists $bug->{$field}, "$field is not included") or diag Dumper($bug); + next; + } + + if ($field =~ /^is_/) { + ok(defined $bug->{$field}, $self->TYPE . ": $field is not null"); + is( + $bug->{$field} ? 1 : 0, + $expect->{$field} ? 1 : 0, + $self->TYPE . ": $field has the right boolean value" + ); + } + elsif ($field eq 'cc') { + foreach my $cc_item (@{$expect->{cc} || []}) { + ok( + grep($_ eq $cc_item, @{$bug->{cc}}), + $self->TYPE . ": $field contains $cc_item" + ); + } + } + elsif ($field eq 'creation_time' or $field eq 'last_change_time') { + my $creation_day; + + # XML-RPC and JSON-RPC have different date formats. + if ($self->isa('QA::RPC::XMLRPC')) { + $creation_day = $creation_time->ymd(''); + } + else { + $creation_day = $creation_time->ymd; + } + + like( + $bug->{$field}, + qr/^\Q${creation_day}\ET\d\d:\d\d:\d\d/, + $self->TYPE . ": $field has the right format" + ); + } + else { + is_deeply($bug->{$field}, $expect->{$field}, + $self->TYPE . ": $field value is correct"); } + } } 1; diff --git a/qa/t/lib/QA/RPC/JSONRPC.pm b/qa/t/lib/QA/RPC/JSONRPC.pm index 4175b10fc..1e43e9eaf 100644 --- a/qa/t/lib/QA/RPC/JSONRPC.pm +++ b/qa/t/lib/QA/RPC/JSONRPC.pm @@ -11,24 +11,26 @@ package QA::RPC::JSONRPC; use strict; use QA::RPC; -BEGIN { - our @ISA = qw(QA::RPC); - if (eval { require JSON::RPC::Client }) { - push(@ISA, 'JSON::RPC::Client'); - } - else { - require JSON::RPC::Legacy::Client; - push(@ISA, 'JSON::RPC::Legacy::Client'); - } +BEGIN { + our @ISA = qw(QA::RPC); + + if (eval { require JSON::RPC::Client }) { + push(@ISA, 'JSON::RPC::Client'); + } + else { + require JSON::RPC::Legacy::Client; + push(@ISA, 'JSON::RPC::Legacy::Client'); + } } use URI::Escape; use constant DATETIME_REGEX => qr/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$/; + sub TYPE { - my ($self) = @_; - return $self->bz_get_mode ? 'JSON-RPC GET' : 'JSON-RPC'; + my ($self) = @_; + return $self->bz_get_mode ? 'JSON-RPC GET' : 'JSON-RPC'; } ################################# @@ -36,85 +38,88 @@ sub TYPE { ################################# sub ua { - my $self = shift; - if ($self->{ua} and not $self->{ua}->isa('QA::RPC::UserAgent')) { - bless $self->{ua}, 'QA::RPC::UserAgent'; - } - return $self->SUPER::ua(@_); + my $self = shift; + if ($self->{ua} and not $self->{ua}->isa('QA::RPC::UserAgent')) { + bless $self->{ua}, 'QA::RPC::UserAgent'; + } + return $self->SUPER::ua(@_); } sub transport { $_[0]->ua } sub bz_get_mode { - my ($self, $value) = @_; - $self->{bz_get_mode} = $value if @_ > 1; - return $self->{bz_get_mode}; + my ($self, $value) = @_; + $self->{bz_get_mode} = $value if @_ > 1; + return $self->{bz_get_mode}; } sub _bz_callback { - my ($self, $value) = @_; - $self->{bz_callback} = $value if @_ > 1; - return $self->{bz_callback}; + my ($self, $value) = @_; + $self->{bz_callback} = $value if @_ > 1; + return $self->{bz_callback}; } sub call { - my $self = shift; - my ($method, $args) = @_; - my %params = ( method => $method ); - $params{params} = $args ? [$args] : []; - - my $config = $self->bz_config; - my $url = $config->{browser_url} . "/" - . $config->{bugzilla_installation} . "/jsonrpc.cgi"; - my $result; - if ($self->bz_get_mode) { - my $method_escaped = uri_escape($method); - $url .= "?method=$method_escaped"; - if (my $cred = $self->_bz_credentials) { - $args->{Bugzilla_login} = $cred->{user} - if !exists $args->{Bugzilla_login}; - $args->{Bugzilla_password} = $cred->{pass} - if !exists $args->{Bugzilla_password}; - } - if ($args) { - my $params_json = $self->json->encode($args); - my $params_escaped = uri_escape($params_json); - $url .= "¶ms=$params_escaped"; - } - if ($self->version eq '1.1') { - $url .= "&version=1.1"; - } - my $callback = delete $args->{callback}; - if (defined $callback) { - $self->_bz_callback($callback); - $url .= "&callback=" . uri_escape($callback); - } - $result = $self->SUPER::call($url); + my $self = shift; + my ($method, $args) = @_; + my %params = (method => $method); + $params{params} = $args ? [$args] : []; + + my $config = $self->bz_config; + my $url + = $config->{browser_url} . "/" + . $config->{bugzilla_installation} + . "/jsonrpc.cgi"; + my $result; + if ($self->bz_get_mode) { + my $method_escaped = uri_escape($method); + $url .= "?method=$method_escaped"; + if (my $cred = $self->_bz_credentials) { + $args->{Bugzilla_login} = $cred->{user} if !exists $args->{Bugzilla_login}; + $args->{Bugzilla_password} = $cred->{pass} + if !exists $args->{Bugzilla_password}; } - else { - $result = $self->SUPER::call($url, \%params); + if ($args) { + my $params_json = $self->json->encode($args); + my $params_escaped = uri_escape($params_json); + $url .= "¶ms=$params_escaped"; } - - if ($result) { - bless $result, 'QA::RPC::JSONRPC::ReturnObject'; + if ($self->version eq '1.1') { + $url .= "&version=1.1"; + } + my $callback = delete $args->{callback}; + if (defined $callback) { + $self->_bz_callback($callback); + $url .= "&callback=" . uri_escape($callback); } - return $result; + $result = $self->SUPER::call($url); + } + else { + $result = $self->SUPER::call($url, \%params); + } + + if ($result) { + bless $result, 'QA::RPC::JSONRPC::ReturnObject'; + } + return $result; } sub _get { - my $self = shift; - my $result = $self->SUPER::_get(@_); - # Simple JSONP support for tests. We just remove the callback from - # the return value. - my $callback = $self->_bz_callback; - if (defined $callback and $result->is_success) { - my $content = $result->content; - $content =~ s/^(?:\/\*\*\/)?\Q$callback(\E(.*)\)$/$1/s; - $result->content($content); - # We don't need this anymore, and we don't want it to affect - # future calls. - delete $self->{bz_callback}; - } - return $result; + my $self = shift; + my $result = $self->SUPER::_get(@_); + + # Simple JSONP support for tests. We just remove the callback from + # the return value. + my $callback = $self->_bz_callback; + if (defined $callback and $result->is_success) { + my $content = $result->content; + $content =~ s/^(?:\/\*\*\/)?\Q$callback(\E(.*)\)$/$1/s; + $result->content($content); + + # We don't need this anymore, and we don't want it to affect + # future calls. + delete $self->{bz_callback}; + } + return $result; } 1; @@ -123,13 +128,13 @@ package QA::RPC::JSONRPC::ReturnObject; use strict; BEGIN { - if (eval { require JSON::RPC::Client }) { - our @ISA = qw(JSON::RPC::ReturnObject); - } - else { - require JSON::RPC::Legacy::Client; - our @ISA = qw(JSON::RPC::Legacy::ReturnObject); - } + if (eval { require JSON::RPC::Client }) { + our @ISA = qw(JSON::RPC::ReturnObject); + } + else { + require JSON::RPC::Legacy::Client; + our @ISA = qw(JSON::RPC::Legacy::ReturnObject); + } } ################################# @@ -137,8 +142,8 @@ BEGIN { ################################# sub faultstring { $_[0]->{content}->{error}->{message} } -sub faultcode { $_[0]->{content}->{error}->{code} } -sub fault { $_[0]->is_error } +sub faultcode { $_[0]->{content}->{error}->{code} } +sub fault { $_[0]->is_error } 1; @@ -151,18 +156,19 @@ use base qw(LWP::UserAgent); ######################################## sub send_request { - my $self = shift; - my $response = $self->SUPER::send_request(@_); - $self->http_response($response); - # JSON::RPC::Client can't handle 500 responses, even though - # they're required by the JSON-RPC spec. - $response->code(200); - return $response; + my $self = shift; + my $response = $self->SUPER::send_request(@_); + $self->http_response($response); + + # JSON::RPC::Client can't handle 500 responses, even though + # they're required by the JSON-RPC spec. + $response->code(200); + return $response; } # Copied directly from SOAP::Lite::Transport::HTTP. sub http_response { - my $self = shift; - if (@_) { $self->{'_http_response'} = shift; return $self } - return $self->{'_http_response'}; + my $self = shift; + if (@_) { $self->{'_http_response'} = shift; return $self } + return $self->{'_http_response'}; } diff --git a/qa/t/lib/QA/RPC/XMLRPC.pm b/qa/t/lib/QA/RPC/XMLRPC.pm index d88d4092e..6e63852eb 100644 --- a/qa/t/lib/QA/RPC/XMLRPC.pm +++ b/qa/t/lib/QA/RPC/XMLRPC.pm @@ -11,7 +11,7 @@ package QA::RPC::XMLRPC; use strict; use base qw(QA::RPC XMLRPC::Lite); -use constant TYPE => 'XML-RPC'; +use constant TYPE => 'XML-RPC'; use constant DATETIME_REGEX => qr/^\d{8}T\d\d:\d\d:\d\d$/; 1; diff --git a/qa/t/lib/QA/Tests.pm b/qa/t/lib/QA/Tests.pm index 86fc06ad1..3d53cefcc 100644 --- a/qa/t/lib/QA/Tests.pm +++ b/qa/t/lib/QA/Tests.pm @@ -11,96 +11,108 @@ package QA::Tests; use strict; use base qw(Exporter); our @EXPORT_OK = qw( - PRIVATE_BUG_USER - STANDARD_BUG_TESTS - bug_tests - create_bug_fields + PRIVATE_BUG_USER + STANDARD_BUG_TESTS + bug_tests + create_bug_fields ); -use constant INVALID_BUG_ID => -1; +use constant INVALID_BUG_ID => -1; use constant INVALID_BUG_ALIAS => 'aaaaaaa12345'; -use constant PRIVATE_BUG_USER => 'QA_Selenium_TEST'; +use constant PRIVATE_BUG_USER => 'QA_Selenium_TEST'; use constant CREATE_BUG => { - 'priority' => 'Highest', - 'status' => 'CONFIRMED', - 'version' => 'unspecified', - 'creator' => 'editbugs', - 'description' => '-- Comment Created By Bugzilla XML-RPC Tests --', - 'cc' => ['unprivileged'], - 'component' => 'c1', - 'platform' => 'PC', - # It's necessary to assign the bug to somebody who isn't in the - # timetracking group, for the Bug.update tests. - 'assigned_to' => PRIVATE_BUG_USER, - 'summary' => 'WebService Test Bug', - 'product' => 'Another Product', - 'op_sys' => 'Linux', - 'severity' => 'normal', - 'qa_contact' => 'canconfirm', - version => 'Another1', - url => 'https://www.bugzilla.org/', - target_milestone => 'AnotherMS1', + 'priority' => 'Highest', + 'status' => 'CONFIRMED', + 'version' => 'unspecified', + 'creator' => 'editbugs', + 'description' => '-- Comment Created By Bugzilla XML-RPC Tests --', + 'cc' => ['unprivileged'], + 'component' => 'c1', + 'platform' => 'PC', + + # It's necessary to assign the bug to somebody who isn't in the + # timetracking group, for the Bug.update tests. + 'assigned_to' => PRIVATE_BUG_USER, + 'summary' => 'WebService Test Bug', + 'product' => 'Another Product', + 'op_sys' => 'Linux', + 'severity' => 'normal', + 'qa_contact' => 'canconfirm', + version => 'Another1', + url => 'https://www.bugzilla.org/', + target_milestone => 'AnotherMS1', }; sub create_bug_fields { - my ($config) = @_; - my %bug = %{ CREATE_BUG() }; - foreach my $field (qw(creator assigned_to qa_contact)) { - my $value = $bug{$field}; - $bug{$field} = $config->{"${value}_user_login"}; - } - $bug{cc} = [map { $config->{$_ . "_user_login"} } @{ $bug{cc} }]; - return \%bug; + my ($config) = @_; + my %bug = %{CREATE_BUG()}; + foreach my $field (qw(creator assigned_to qa_contact)) { + my $value = $bug{$field}; + $bug{$field} = $config->{"${value}_user_login"}; + } + $bug{cc} = [map { $config->{$_ . "_user_login"} } @{$bug{cc}}]; + return \%bug; } sub bug_tests { - my ($public_id, $private_id) = @_; - return [ - { args => { ids => [$private_id] }, + my ($public_id, $private_id) = @_; + return [ + { + args => {ids => [$private_id]}, error => "You are not authorized to access", test => 'Logged-out user cannot access a private bug', }, - { args => { ids => [$public_id] }, + { + args => {ids => [$public_id]}, test => 'Logged-out user can access a public bug.', }, - { args => { ids => [INVALID_BUG_ID] }, + { + args => {ids => [INVALID_BUG_ID]}, error => "It does not seem like bug number", test => 'Passing invalid bug id returns error "Invalid Bug ID"', }, - { args => { ids => [undef] }, + { + args => {ids => [undef]}, error => "You must enter a valid bug number", test => 'Passing undef as bug id param returns error "Invalid Bug ID"', }, - { args => { ids => [INVALID_BUG_ALIAS] }, + { + args => {ids => [INVALID_BUG_ALIAS]}, error => "nor an alias to a bug", test => 'Passing invalid bug alias returns error "Invalid Bug Alias"', }, - { user => 'editbugs', - args => { ids => [$private_id] }, + { + user => 'editbugs', + args => {ids => [$private_id]}, error => "You are not authorized to access", test => 'Access to a private bug is denied to a user without privs', }, - { user => 'unprivileged', - args => { ids => [$public_id] }, + { + user => 'unprivileged', + args => {ids => [$public_id]}, test => 'User without privs can access a public bug', }, - { user => 'admin', - args => { ids => [$public_id] }, + { + user => 'admin', + args => {ids => [$public_id]}, test => 'Admin can access a public bug.', }, - { user => PRIVATE_BUG_USER, - args => { ids => [$private_id] }, + { + user => PRIVATE_BUG_USER, + args => {ids => [$private_id]}, test => 'User with privs can successfully access a private bug', }, + # This helps webservice_bug_attachment get private attachment ids # from the public bug, and doesn't hurt for the other tests. - { user => PRIVATE_BUG_USER, - args => { ids => [$public_id] }, + { + user => PRIVATE_BUG_USER, + args => {ids => [$public_id]}, test => 'User with privs can also access the public bug', }, - ]; + ]; } use constant STANDARD_BUG_TESTS => bug_tests('public_bug', 'private_bug'); diff --git a/qa/t/lib/QA/Util.pm b/qa/t/lib/QA/Util.pm index bf9151fee..fd584975a 100644 --- a/qa/t/lib/QA/Util.pm +++ b/qa/t/lib/QA/Util.pm @@ -22,72 +22,74 @@ use URI::QueryParam; # Fixes wide character warnings BEGIN { - my $builder = Test::More->builder; - binmode $builder->output, ":encoding(utf8)"; - binmode $builder->failure_output, ":encoding(utf8)"; - binmode $builder->todo_output, ":encoding(utf8)"; + my $builder = Test::More->builder; + binmode $builder->output, ":encoding(utf8)"; + binmode $builder->failure_output, ":encoding(utf8)"; + binmode $builder->todo_output, ":encoding(utf8)"; } use base qw(Exporter); @QA::Util::EXPORT = qw( - trim - url_quote - random_string - - log_in - logout - file_bug_in_product - create_bug - edit_bug - edit_bug_and_return - go_to_bug - go_to_home - go_to_admin - edit_product - add_product - open_advanced_search_page - set_parameters - screenshot_page - - get_selenium - get_rpc_clients - check_page_load - - WAIT_TIME - CHROME_MODE + trim + url_quote + random_string + + log_in + logout + file_bug_in_product + create_bug + edit_bug + edit_bug_and_return + go_to_bug + go_to_home + go_to_admin + edit_product + add_product + open_advanced_search_page + set_parameters + screenshot_page + + get_selenium + get_rpc_clients + check_page_load + + WAIT_TIME + CHROME_MODE ); # How long we wait for pages to load. use constant WAIT_TIME => 60000; -use constant CONF_FILE => $ENV{BZ_QA_CONF_FILE} // "../config/selenium_test.conf"; +use constant CONF_FILE => $ENV{BZ_QA_CONF_FILE} + // "../config/selenium_test.conf"; use constant CHROME_MODE => 1; -use constant NDASH => chr(0x2013); +use constant NDASH => chr(0x2013); ##################### # Utility Functions # ##################### sub random_string { - my $size = shift || 30; # default to 30 chars if nothing specified - return join("", map{ ('0'..'9','a'..'z','A'..'Z')[rand 62] } (1..$size)); + my $size = shift || 30; # default to 30 chars if nothing specified + return + join("", map { ('0' .. '9', 'a' .. 'z', 'A' .. 'Z')[rand 62] } (1 .. $size)); } # Remove consecutive as well as leading and trailing whitespaces. sub trim { - my ($str) = @_; - if ($str) { - $str =~ s/[\r\n\t\s]+/ /g; - $str =~ s/^\s+//g; - $str =~ s/\s+$//g; - } - return $str; + my ($str) = @_; + if ($str) { + $str =~ s/[\r\n\t\s]+/ /g; + $str =~ s/^\s+//g; + $str =~ s/\s+$//g; + } + return $str; } # This originally came from CGI.pm, by Lincoln D. Stein sub url_quote { - my ($toencode) = (@_); - $toencode =~ s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg; - return $toencode; + my ($toencode) = (@_); + $toencode =~ s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg; + return $toencode; } ################### @@ -95,67 +97,73 @@ sub url_quote { ################### sub get_config { - # read the test configuration file - my $conf_file = CONF_FILE; - my $config = do($conf_file) - or die "can't read configuration '$conf_file': $!$@"; - my $uri = URI->new($config->{browser_url}); - if (my $ip_packed = gethostbyname($uri->host)) { - my $ip = inet_ntoa($ip_packed); - $uri->host($ip); - $config->{browser_ip_url} = "$uri"; - } - else { - die "unable to find ip for $config->{browser_url}\n"; - } - return $config; + + # read the test configuration file + my $conf_file = CONF_FILE; + my $config = do($conf_file) + or die "can't read configuration '$conf_file': $!$@"; + my $uri = URI->new($config->{browser_url}); + if (my $ip_packed = gethostbyname($uri->host)) { + my $ip = inet_ntoa($ip_packed); + $uri->host($ip); + $config->{browser_ip_url} = "$uri"; + } + else { + die "unable to find ip for $config->{browser_url}\n"; + } + return $config; } sub get_selenium { - my $chrome_mode = shift; - my $config = get_config(); - - if (!server_is_running) { - die "Selenium Server isn't running!"; - } - - my $sel = Test::WWW::Selenium->new( - host => $config->{host}, - port => $config->{port}, - browser => $chrome_mode ? $config->{experimental_browser_launcher} : $config->{browser}, - browser_url => $config->{browser_url} - ); - - return ($sel, $config); + my $chrome_mode = shift; + my $config = get_config(); + + if (!server_is_running) { + die "Selenium Server isn't running!"; + } + + my $sel = Test::WWW::Selenium->new( + host => $config->{host}, + port => $config->{port}, + browser => $chrome_mode + ? $config->{experimental_browser_launcher} + : $config->{browser}, + browser_url => $config->{browser_url} + ); + + return ($sel, $config); } sub get_xmlrpc_client { - my $config = get_config(); - my $xmlrpc_url = $config->{browser_url} . "/" . - $config->{bugzilla_installation} . "/xmlrpc.cgi"; - - require QA::RPC::XMLRPC; - my $rpc = new QA::RPC::XMLRPC(proxy => $xmlrpc_url); - return ($rpc, $config); + my $config = get_config(); + my $xmlrpc_url + = $config->{browser_url} . "/" + . $config->{bugzilla_installation} + . "/xmlrpc.cgi"; + + require QA::RPC::XMLRPC; + my $rpc = new QA::RPC::XMLRPC(proxy => $xmlrpc_url); + return ($rpc, $config); } sub get_jsonrpc_client { - my ($get_mode) = @_; - require QA::RPC::JSONRPC; - my $rpc = new QA::RPC::JSONRPC(); - # If we don't set a long timeout, then the Bug.add_comment test - # where we add a too-large comment fails. - $rpc->transport->timeout(180); - $rpc->version($get_mode ? '1.1' : '1.0'); - $rpc->bz_get_mode($get_mode); - return $rpc; + my ($get_mode) = @_; + require QA::RPC::JSONRPC; + my $rpc = new QA::RPC::JSONRPC(); + + # If we don't set a long timeout, then the Bug.add_comment test + # where we add a too-large comment fails. + $rpc->transport->timeout(180); + $rpc->version($get_mode ? '1.1' : '1.0'); + $rpc->bz_get_mode($get_mode); + return $rpc; } sub get_rpc_clients { - my ($xmlrpc, $config) = get_xmlrpc_client(); - my $jsonrpc = get_jsonrpc_client(); - my $jsonrpc_get = get_jsonrpc_client('GET'); - return ($config, $xmlrpc, $jsonrpc, $jsonrpc_get); + my ($xmlrpc, $config) = get_xmlrpc_client(); + my $jsonrpc = get_jsonrpc_client(); + my $jsonrpc_get = get_jsonrpc_client('GET'); + return ($config, $xmlrpc, $jsonrpc, $jsonrpc_get); } ################################ @@ -163,182 +171,210 @@ sub get_rpc_clients { ################################ sub go_to_home { - my ($sel, $config) = @_; - $sel->open_ok("/$config->{bugzilla_installation}/", undef, "Go to the home page"); - $sel->set_speed(500); - $sel->title_is("Bugzilla Main Page"); + my ($sel, $config) = @_; + $sel->open_ok("/$config->{bugzilla_installation}/", + undef, "Go to the home page"); + $sel->set_speed(500); + $sel->title_is("Bugzilla Main Page"); } sub screenshot_page { - my ($sel, $filename) = @_; - open my $fh, '>:raw', $filename or die "unable to write $filename: $!"; - binmode $fh; - print $fh decode_base64($sel->capture_entire_page_screenshot_to_string()); - close $fh; + my ($sel, $filename) = @_; + open my $fh, '>:raw', $filename or die "unable to write $filename: $!"; + binmode $fh; + print $fh decode_base64($sel->capture_entire_page_screenshot_to_string()); + close $fh; } # Go to the home/login page and log in. sub log_in { - my ($sel, $config, $user) = @_; - - $sel->open_ok("/$config->{bugzilla_installation}/login", undef, "Go to the home page"); - $sel->title_is("Log in to Bugzilla"); - $sel->type_ok("Bugzilla_login", $config->{"${user}_user_login"}, "Enter $user login name"); - $sel->type_ok("Bugzilla_password", $config->{"${user}_user_passwd"}, "Enter $user password"); - $sel->click_ok("log_in", undef, "Submit credentials"); - $sel->wait_for_page_to_load(WAIT_TIME); - $sel->title_is("Bugzilla Main Page", "User is logged in"); + my ($sel, $config, $user) = @_; + + $sel->open_ok("/$config->{bugzilla_installation}/login", + undef, "Go to the home page"); + $sel->title_is("Log in to Bugzilla"); + $sel->type_ok( + "Bugzilla_login", + $config->{"${user}_user_login"}, + "Enter $user login name" + ); + $sel->type_ok( + "Bugzilla_password", + $config->{"${user}_user_passwd"}, + "Enter $user password" + ); + $sel->click_ok("log_in", undef, "Submit credentials"); + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_is("Bugzilla Main Page", "User is logged in"); } # Log out. Will fail if you are not logged in. sub logout { - my $sel = shift; + my $sel = shift; - $sel->click_ok("link=Log out", undef, "Logout"); - $sel->wait_for_page_to_load_ok(WAIT_TIME); - $sel->title_is("Logged Out"); + $sel->click_ok("link=Log out", undef, "Logout"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Logged Out"); } # Display the bug form to enter a bug in the given product. sub file_bug_in_product { - my ($sel, $product, $classification) = @_; - my $config = get_config(); - - $classification ||= "Unclassified"; - $sel->click_ok('//*[@class="link-file"]//a', undef, "Go create a new bug"); + my ($sel, $product, $classification) = @_; + my $config = get_config(); + + $classification ||= "Unclassified"; + $sel->click_ok('//*[@class="link-file"]//a', undef, "Go create a new bug"); + $sel->wait_for_page_to_load(WAIT_TIME); + my $title = $sel->get_title(); + if ($sel->is_text_present("Select Classification")) { + ok(1, + "More than one enterable classification available. Display them in a list"); + $sel->click_ok("link=$classification", undef, "Choose $classification"); $sel->wait_for_page_to_load(WAIT_TIME); - my $title = $sel->get_title(); - if ($sel->is_text_present("Select Classification")) { - ok(1, "More than one enterable classification available. Display them in a list"); - $sel->click_ok("link=$classification", undef, "Choose $classification"); - $sel->wait_for_page_to_load(WAIT_TIME); - $title = $sel->get_title(); - } - if ($sel->is_text_present("Which product is affected by the problem")) { - ok(1, "Which product is affected by the problem"); - $sel->click_ok("link=Other Products", undef, "Choose full product list"); - $sel->wait_for_page_to_load(WAIT_TIME); - $title = $sel->get_title(); - } - if ($sel->is_text_present($product)) { - ok(1, "Display the list of enterable products"); - $sel->open_ok("/" . $config->{bugzilla_installation} . "/enter_bug.cgi?product=$product&format=__default__", undef, "Choose product $product"); - $sel->wait_for_page_to_load(WAIT_TIME); - } - else { - ok(1, "Only one product available in $classification. Skipping the 'Choose product' page.") - } - $sel->title_is("Enter Bug: $product", "Display form to enter bug data"); - # Always make sure all fields are visible - if ($sel->is_element_present('//input[@value="Show Advanced Fields"]')) { - $sel->click_ok('//input[@value="Show Advanced Fields"]'); - } + $title = $sel->get_title(); + } + if ($sel->is_text_present("Which product is affected by the problem")) { + ok(1, "Which product is affected by the problem"); + $sel->click_ok("link=Other Products", undef, "Choose full product list"); + $sel->wait_for_page_to_load(WAIT_TIME); + $title = $sel->get_title(); + } + if ($sel->is_text_present($product)) { + ok(1, "Display the list of enterable products"); + $sel->open_ok( + "/" + . $config->{bugzilla_installation} + . "/enter_bug.cgi?product=$product&format=__default__", + undef, + "Choose product $product" + ); + $sel->wait_for_page_to_load(WAIT_TIME); + } + else { + ok(1, + "Only one product available in $classification. Skipping the 'Choose product' page." + ); + } + $sel->title_is("Enter Bug: $product", "Display form to enter bug data"); + + # Always make sure all fields are visible + if ($sel->is_element_present('//input[@value="Show Advanced Fields"]')) { + $sel->click_ok('//input[@value="Show Advanced Fields"]'); + } } sub create_bug { - my ($sel, $bug_summary) = @_; - my $ndash = NDASH; - - $sel->click_ok('commit'); - $sel->wait_for_page_to_load_ok(WAIT_TIME); - my $bug_id = $sel->get_value('//input[@name="id" and @type="hidden"]'); - $sel->title_like(qr/$bug_id $ndash( \(.*\))? $bug_summary/, "Bug $bug_id created with summary '$bug_summary'"); - return $bug_id; + my ($sel, $bug_summary) = @_; + my $ndash = NDASH; + + $sel->click_ok('commit'); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + my $bug_id = $sel->get_value('//input[@name="id" and @type="hidden"]'); + $sel->title_like( + qr/$bug_id $ndash( \(.*\))? $bug_summary/, + "Bug $bug_id created with summary '$bug_summary'" + ); + return $bug_id; } sub edit_bug { - my ($sel, $bug_id, $bug_summary, $options) = @_; - my $btn_id = $options ? $options->{id} : 'commit'; - $sel->click_ok($btn_id); - $sel->wait_for_page_to_load_ok(WAIT_TIME); - $sel->is_text_present_ok("Changes submitted for bug $bug_id"); + my ($sel, $bug_id, $bug_summary, $options) = @_; + my $btn_id = $options ? $options->{id} : 'commit'; + $sel->click_ok($btn_id); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->is_text_present_ok("Changes submitted for bug $bug_id"); } sub edit_bug_and_return { - my ($sel, $bug_id, $bug_summary, $options) = @_; - my $ndash = NDASH; - edit_bug($sel, $bug_id, $bug_summary, $options); - $sel->click_ok("//a[contains(\@href, 'show_bug.cgi?id=$bug_id')]"); - $sel->wait_for_page_to_load_ok(WAIT_TIME); - $sel->title_is("$bug_id $ndash $bug_summary", "Returning back to bug $bug_id"); + my ($sel, $bug_id, $bug_summary, $options) = @_; + my $ndash = NDASH; + edit_bug($sel, $bug_id, $bug_summary, $options); + $sel->click_ok("//a[contains(\@href, 'show_bug.cgi?id=$bug_id')]"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("$bug_id $ndash $bug_summary", "Returning back to bug $bug_id"); } # Go to show_bug.cgi. sub go_to_bug { - my ($sel, $bug_id) = @_; - - $sel->type_ok("quicksearch_top", $bug_id); - $sel->submit("header-search"); - $sel->wait_for_page_to_load_ok(WAIT_TIME); - my $bug_title = $sel->get_title(); - utf8::encode($bug_title) if utf8::is_utf8($bug_title); - $sel->title_like(qr/^$bug_id /, $bug_title); + my ($sel, $bug_id) = @_; + + $sel->type_ok("quicksearch_top", $bug_id); + $sel->submit("header-search"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + my $bug_title = $sel->get_title(); + utf8::encode($bug_title) if utf8::is_utf8($bug_title); + $sel->title_like(qr/^$bug_id /, $bug_title); } # Go to admin.cgi. sub go_to_admin { - my $sel = shift; + my $sel = shift; - $sel->click_ok("link=Administration", undef, "Go to the Admin page"); - $sel->wait_for_page_to_load(WAIT_TIME); - $sel->title_like(qr/^Administer your installation/, "Display admin.cgi"); + $sel->click_ok("link=Administration", undef, "Go to the Admin page"); + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_like(qr/^Administer your installation/, "Display admin.cgi"); } # Go to editproducts.cgi and display the given product. sub edit_product { - my ($sel, $product, $classification) = @_; - - $classification ||= "Unclassified"; - go_to_admin($sel); - $sel->click_ok("link=Products", undef, "Go to the Products page"); + my ($sel, $product, $classification) = @_; + + $classification ||= "Unclassified"; + go_to_admin($sel); + $sel->click_ok("link=Products", undef, "Go to the Products page"); + $sel->wait_for_page_to_load(WAIT_TIME); + my $title = $sel->get_title(); + if ($title eq "Select Classification") { + ok(1, + "More than one enterable classification available. Display them in a list"); + $sel->click_ok("link=$classification", undef, "Choose $classification"); $sel->wait_for_page_to_load(WAIT_TIME); - my $title = $sel->get_title(); - if ($title eq "Select Classification") { - ok(1, "More than one enterable classification available. Display them in a list"); - $sel->click_ok("link=$classification", undef, "Choose $classification"); - $sel->wait_for_page_to_load(WAIT_TIME); - } - else { - $sel->title_is("Select product", "Display the list of enterable products"); - } - $sel->click_ok("link=$product", undef, "Choose $product"); - $sel->wait_for_page_to_load(WAIT_TIME); - $sel->title_is("Edit Product '$product'", "Display properties of $product"); + } + else { + $sel->title_is("Select product", "Display the list of enterable products"); + } + $sel->click_ok("link=$product", undef, "Choose $product"); + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_is("Edit Product '$product'", "Display properties of $product"); } sub add_product { - my ($sel, $classification) = @_; - - $classification ||= "Unclassified"; - go_to_admin($sel); - $sel->click_ok("link=Products", undef, "Go to the Products page"); - $sel->wait_for_page_to_load(WAIT_TIME); - my $title = $sel->get_title(); - if ($title eq "Select Classification") { - ok(1, "More than one enterable classification available. Display them in a list"); - $sel->click_ok("//a[contains(\@href, 'editproducts.cgi?action=add&classification=$classification')]", - undef, "Add product to $classification"); - } - else { - $sel->title_is("Select product", "Display the list of enterable products"); - $sel->click_ok("link=Add", undef, "Add a new product"); - } - $sel->wait_for_page_to_load(WAIT_TIME); - $sel->title_is("Add Product", "Display the new product form"); + my ($sel, $classification) = @_; + + $classification ||= "Unclassified"; + go_to_admin($sel); + $sel->click_ok("link=Products", undef, "Go to the Products page"); + $sel->wait_for_page_to_load(WAIT_TIME); + my $title = $sel->get_title(); + if ($title eq "Select Classification") { + ok(1, + "More than one enterable classification available. Display them in a list"); + $sel->click_ok( + "//a[contains(\@href, 'editproducts.cgi?action=add&classification=$classification')]", + undef, + "Add product to $classification" + ); + } + else { + $sel->title_is("Select product", "Display the list of enterable products"); + $sel->click_ok("link=Add", undef, "Add a new product"); + } + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_is("Add Product", "Display the new product form"); } sub open_advanced_search_page { - my $sel = shift; - - $sel->click_ok('//*[@class="link-search"]//a'); + my $sel = shift; + + $sel->click_ok('//*[@class="link-search"]//a'); + $sel->wait_for_page_to_load(WAIT_TIME); + my $title = $sel->get_title(); + if ($title eq "Simple Search") { + ok(1, "Display the simple search form"); + $sel->click_ok("link=Advanced Search"); $sel->wait_for_page_to_load(WAIT_TIME); - my $title = $sel->get_title(); - if ($title eq "Simple Search") { - ok(1, "Display the simple search form"); - $sel->click_ok("link=Advanced Search"); - $sel->wait_for_page_to_load(WAIT_TIME); - } - $sel->title_is("Search for bugs", "Display the Advanced search form"); + } + $sel->title_is("Search for bugs", "Display the Advanced search form"); } # $params is a hashref of the form: @@ -354,74 +390,75 @@ sub open_advanced_search_page { # undef is for radio buttons (in which case the parameter must be the ID of the radio button) # value => 'foo' is the value of the parameter (either text or label) sub set_parameters { - my ($sel, $params) = @_; - - go_to_admin($sel); - $sel->click_ok("link=Parameters", undef, "Go to the Config Parameters page"); - $sel->wait_for_page_to_load(WAIT_TIME); - $sel->title_is("Configuration: General"); - my $last_section = "General"; - - foreach my $section (keys %$params) { - if ($section ne $last_section) { - $sel->click_ok("link=$section"); - $sel->wait_for_page_to_load_ok(WAIT_TIME); - $sel->title_is("Configuration: $section"); - $last_section = $section; + my ($sel, $params) = @_; + + go_to_admin($sel); + $sel->click_ok("link=Parameters", undef, "Go to the Config Parameters page"); + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_is("Configuration: General"); + my $last_section = "General"; + + foreach my $section (keys %$params) { + if ($section ne $last_section) { + $sel->click_ok("link=$section"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Configuration: $section"); + $last_section = $section; + } + my $param_list = $params->{$section}; + foreach my $param (keys %$param_list) { + my $data = $param_list->{$param}; + if (defined $data) { + my $type = $data->{type}; + my $value = $data->{value}; + + if ($type eq 'text') { + $sel->type_ok($param, $value); + } + elsif ($type eq 'select') { + $sel->select_ok($param, "label=$value"); } - my $param_list = $params->{$section}; - foreach my $param (keys %$param_list) { - my $data = $param_list->{$param}; - if (defined $data) { - my $type = $data->{type}; - my $value = $data->{value}; - - if ($type eq 'text') { - $sel->type_ok($param, $value); - } - elsif ($type eq 'select') { - $sel->select_ok($param, "label=$value"); - } - else { - ok(0, "Unknown parameter type: $type"); - } - } - else { - # If the value is undefined, then the param name is - # the ID of the radio button. - $sel->click_ok($param); - } + else { + ok(0, "Unknown parameter type: $type"); } - $sel->click_ok('//input[@type="submit" and @value="Save Changes"]', undef, "Save Changes"); - $sel->wait_for_page_to_load_ok(WAIT_TIME); - $sel->title_is("Parameters Updated"); + } + else { + # If the value is undefined, then the param name is + # the ID of the radio button. + $sel->click_ok($param); + } } + $sel->click_ok('//input[@type="submit" and @value="Save Changes"]', + undef, "Save Changes"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Parameters Updated"); + } } my @ANY_KEYS = qw( t token ); sub check_page_load { - my ($sel, $wait, $expected) = @_; - my $expected_uri = URI->new($expected); - $sel->wait_for_page_to_load_ok($wait); - my $uri = URI->new($sel->get_location); - - foreach my $u ($expected_uri, $uri) { - $u->host('HOSTNAME'); - foreach my $any_key (@ANY_KEYS) { - if ($u->query_param($any_key)) { - $u->query_param($any_key => '__ANYTHING__'); - } - } + my ($sel, $wait, $expected) = @_; + my $expected_uri = URI->new($expected); + $sel->wait_for_page_to_load_ok($wait); + my $uri = URI->new($sel->get_location); + + foreach my $u ($expected_uri, $uri) { + $u->host('HOSTNAME'); + foreach my $any_key (@ANY_KEYS) { + if ($u->query_param($any_key)) { + $u->query_param($any_key => '__ANYTHING__'); + } } + } - if ($expected_uri->query_param('id')) { - if ($expected_uri->query_param('id') eq '__BUG_ID__') { - $uri->query_param('id' => '__BUG_ID__'); - } + if ($expected_uri->query_param('id')) { + if ($expected_uri->query_param('id') eq '__BUG_ID__') { + $uri->query_param('id' => '__BUG_ID__'); } - my ($pkg, $file, $line) = caller; - is($uri, $expected_uri, "checking location on $file line $line"); + } + my ($pkg, $file, $line) = caller; + is($uri, $expected_uri, "checking location on $file line $line"); } 1; |