# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. use 5.14.0; use strict; use warnings; use FindBin qw($RealBin); use lib "$RealBin/../lib", "$RealBin/../../local/lib/perl5"; use Data::Dumper; use Test::More; use List::Util qw(first); use QA::Util; my ($config, @clients) = get_rpc_clients(); plan tests => ($config->{test_extensions} ? 1338 : 1320); use constant INVALID_FIELD_NAME => 'invalid_field'; use constant INVALID_FIELD_ID => -1; sub GLOBAL_GENERAL_FIELDS { my @fields = qw( attach_data.thedata attachments.description attachments.filename attachments.isobsolete attachments.ispatch attachments.isprivate attachments.mimetype attachments.submitter flagtypes.name requestees.login_name setters.login_name alias assigned_to blocked bug_file_loc bug_group bug_id cc cclist_accessible classification commenter content creation_ts days_elapsed delta_ts dependson everconfirmed keywords longdesc longdescs.isprivate owner_idle_time product qa_contact reporter reporter_accessible see_also short_desc status_whiteboard deadline estimated_time percentage_complete remaining_time work_time ); push(@fields, 'votes') if QA::Util::get_config()->{test_extensions}; return @fields; } use constant STANDARD_SELECT_FIELDS => qw(bug_severity bug_status op_sys priority rep_platform resolution); use constant ALL_SELECT_FIELDS => (STANDARD_SELECT_FIELDS, qw(cf_qa_status cf_single_select)); use constant PRODUCT_FIELDS => qw(version target_milestone component); use constant ALL_FIELDS => (GLOBAL_GENERAL_FIELDS, ALL_SELECT_FIELDS, PRODUCT_FIELDS); use constant MANDATORY_FIELDS => qw(short_desc product version component); use constant PUBLIC_PRODUCT => 'Another Product'; use constant PRIVATE_PRODUCT => 'QA-Selenium-TEST'; sub get_field { my ($fields, $field) = @_; return first { $_->{name} eq $field } @$fields; } sub get_products_from_field { my $field = shift; my %products; foreach my $value (@{ $field->{values} }) { foreach my $vis_value (@{ $value->{visibility_values} }) { $products{$vis_value} = 1; } } return \%products; } our %field_ids; foreach my $rpc (@clients) { my $call = $rpc->bz_call_success('Bug.fields'); my $fields = $call->result->{fields}; foreach my $field (ALL_FIELDS) { my $field_data = get_field($fields, $field); ok($field_data, "$field is in the returned result") or diag(Dumper($fields)); $field_ids{$field} = $field_data->{id}; if (grep($_ eq $field, MANDATORY_FIELDS)) { ok($field_data->{is_mandatory}, "$field is mandatory"); } else { ok(!$field_data->{is_mandatory}, "$field is not mandatory"); } } foreach my $field (ALL_SELECT_FIELDS, PRODUCT_FIELDS) { my $field_data = get_field($fields, $field); ok(defined $field_data->{visibility_values}, "$field has visibility_values defined"); my $field_vis_undefs = grep { !defined $_ } @{ $field_data->{visibility_values} }; is($field_vis_undefs, 0, "$field.visibility_values has no undefs") or diag(Dumper($field_data->{visibility_values})); ok(defined $field_data->{values}, "$field has 'values' defined"); my $num_values = scalar @{ $field_data->{values} }; ok($num_values, "$field has $num_values values"); # The first bug status is a fake one and has no name, so we choose the 2nd item. my $first_value = $field_data->{values}->[1]; ok(defined $first_value->{name}, 'The first value has a name') or diag(Dumper($field_data->{values})); # The sortkey for milestones can be negative. cmp_ok($first_value->{sortkey}, '=~', qr/^-?\d+$/, "The first value has a numeric sortkey"); ok(defined $first_value->{visibility_values}, "$field has visibilty_values defined on its first value") or diag(Dumper($field_data->{values})); my @value_visibility_values = map { @{ $_->{visibility_values} } } @{ $field_data->{values} }; my $undefs = grep { !defined $_ } @value_visibility_values; is($undefs, 0, "$field.values.visibility_values has no undefs"); } foreach my $field (PRODUCT_FIELDS) { my $field_data = get_field($fields, $field); is($field_data->{value_field}, 'product', "The value_field for $field is 'product'"); my $products = get_products_from_field($field_data); ok($products->{+PUBLIC_PRODUCT}, "$field values are returned for the public product"); ok(!$products->{+PRIVATE_PRODUCT}, "No $field values are returned for the private product"); } } my @all_tests = ( { args => { ids => [values %field_ids], names => [ALL_FIELDS] }, test => 'Getting all fields by name and id simultaneously', count => scalar ALL_FIELDS }, { args => { names => [INVALID_FIELD_NAME] }, error => "There is no field named", test => 'Invalid field name' }, { args => { ids => [INVALID_FIELD_ID] }, error => 'must be numeric', test => 'Invalid field id' }, { user => 'QA_Selenium_TEST', args => { names => [PRODUCT_FIELDS] }, test => 'Getting product-specific fields as a privileged user', count => scalar PRODUCT_FIELDS, product_private_values => 1 }, ); foreach my $field (ALL_FIELDS) { push(@all_tests, { args => { names => [$field] }, test => "Logged-out users can get the $field field by name" }); push(@all_tests, { args => { ids => [$field_ids{$field}] }, test => "Logged-out users can get the $field by id" }); } sub post_success { my ($call, $t) = @_; my $fields = $call->result->{fields}; my $count = $t->{count}; $count = 1 if !defined $count; is(scalar @$fields, $count, "Exactly $count field(s) returned"); if ($t->{product_private_values}) { foreach my $field (@$fields) { my $name = $field->{name}; my $field_data = get_field($fields, $name); my $products = get_products_from_field($field_data); ok($products->{+PUBLIC_PRODUCT}, "$name values are returned for the public product"); ok($products->{+PRIVATE_PRODUCT}, "$name values are returned for the private product"); } } } foreach my $rpc (@clients) { $rpc->bz_run_tests(tests => \@all_tests, method => 'Bug.fields', post_success => \&post_success); }