# 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 QA::Util; use MIME::Base64 qw(encode_base64 decode_base64); use Test::More tests => 187; my ($config, $xmlrpc, $jsonrpc, $jsonrpc_get) = get_rpc_clients(); use constant INVALID_BUG_ID => -1; use constant INVALID_BUG_ALIAS => random_string(20); use constant PRIVS_USER => 'QA_Selenium_TEST'; sub attach { my ($id, $override) = @_; my %fields = ( ids => [$id], data => 'data-' . random_string(100), file_name => 'file_name-' . random_string(60), summary => 'summary-' . random_string(100), content_type => 'text/plain', comment => 'comment-' . random_string(100), ); foreach my $key (keys %{ $override || {} }) { my $value = $override->{$key}; if (defined $value) { $fields{$key} = $value; } else { delete $fields{$key}; } } return \%fields; } my ($public_bug, $private_bug) = $xmlrpc->bz_create_test_bugs('private'); my $public_id = $public_bug->{id}; my $private_id = $private_bug->{id}; my @tests = ( # Permissions { args => attach($public_id), error => 'You must log in', test => 'Logged-out user cannot add an attachment to a public bug', }, { args => attach($private_id), error => "You must log in", test => 'Logged-out user cannot add an attachment to a private bug', }, { user => 'editbugs', args => attach($private_id), error => "not authorized to access", test => "Editbugs user can't add an attachment to a private bug", }, # Test ID parameter { user => 'unprivileged', args => attach(undef, { ids => undef }), error => 'a ids argument', test => 'Failing to pass the "ids" param fails', }, { user => 'unprivileged', args => attach(INVALID_BUG_ID), error => "not a valid bug number", test => 'Passing invalid bug id returns error "Invalid Bug ID"', }, { user => 'unprivileged', args => attach(''), error => "You must enter a valid bug number", test => 'Passing empty bug id returns error "Invalid Bug ID"', }, { user => 'unprivileged', args => attach(INVALID_BUG_ALIAS), error => "nor an alias to a bug", test => 'Passing invalid bug alias returns error "Invalid Bug Alias"', }, # Test Comment parameter { user => 'unprivileged', args => attach($public_id, { data => undef }), error => 'a data argument', test => 'Failing to pass the "data" parameter fails', }, { user => 'unprivileged', args => attach($public_id, { data => '' }), error => "The file you are trying to attach is empty", test => 'Passing empty data fails', }, { user => 'unprivileged', args => attach($public_id, { data => random_string(300_000) }), error => "Attachments cannot be more than", test => "Passing an attachment that's too large fails", }, # Test the private parameter { user => 'unprivileged', args => attach($public_id, { is_private => 1 }), error => 'attachments as private', test => 'Unprivileged user cannot add a private attachment' }, # Content-type { user => 'unprivileged', args => attach($public_id, { content_type => 'foo/bar' }), error => "Valid types must be of the form", test => "Well-formed but invalid content type fails", }, { user => 'unprivileged', args => attach($public_id, { content_type => undef }), error => 'Valid types must be of the form', test => "Failing to pass content_type fails", }, { user => 'unprivileged', args => attach($public_id, { content_type => '' }), error => 'Valid types must be of the form', test => "Empty content type fails", }, # Summary { user => 'unprivileged', args => attach($public_id, { summary => undef }), error => 'You must enter a description for the attachment', test => "Failing to pass summary fails", }, { user => 'unprivileged', args => attach($public_id, { summary => '' }), error => 'You must enter a description for the attachment', test => "Empty summary fails", }, # Filename { user => 'unprivileged', args => attach($public_id, { file_name => undef }), error => 'You did not specify a file to attach', test => "Failing to pass file_name fails", }, { user => 'unprivileged', args => attach($public_id, { file_name => '' }), error => 'You did not specify a file to attach', test => "Empty file_name fails", }, # Success tests { user => 'unprivileged', args => attach($public_id), test => 'Unprivileged user can add an attachment to a public bug', }, { user => 'unprivileged', args => attach($public_id, { is_patch => 1, content_type => undef }), test => 'Attaching a patch with no content type works', }, { user => 'unprivileged', args => attach($public_id, { is_patch => 1, content_type => 'application/octet-stream' }), test => 'Attaching a patch with a bad content_type works', }, { user => PRIVS_USER, args => attach($private_id), test => 'Privileged user can add an attachment to a private bug', }, { user => PRIVS_USER, args => attach($public_id, { is_private => 1 }), test => 'Insidergroup user can add a private attachment', }, ); $jsonrpc_get->bz_call_fail('Bug.add_attachment', attach($public_id), 'must use HTTP POST', 'add_attachment fails over GET'); foreach my $rpc ($jsonrpc, $xmlrpc) { $rpc->bz_run_tests(tests => \@tests, method => 'Bug.add_attachment', post_success => \&post_success, pre_call => \&pre_call); } # We have to encode data manually when using JSON-RPC, else it fails. sub pre_call { my ($t, $rpc) = @_; return if !$rpc->isa('QA::RPC::JSONRPC'); return if !defined $t->{args}->{data}; $t->{args}->{data} = encode_base64($t->{args}->{data}, ''); } sub post_success { my ($call, $t, $rpc) = @_; my $ids = $call->result->{ids}; $call = $rpc->bz_call_success("Bug.attachments", {attachment_ids => $ids}); my $attachments = $call->result->{attachments}; foreach my $id (keys %$attachments) { my $attachment = $attachments->{$id}; if ($t->{args}->{is_private}) { ok($attachment->{is_private}, $rpc->TYPE . ": Attachment $id is private"); } else { ok(!$attachment->{is_private}, $rpc->TYPE . ": Attachment $id is NOT private"); } if ($t->{args}->{is_patch}) { is($attachment->{content_type}, 'text/plain', $rpc->TYPE . ": Patch $id content type is text/plain"); } else { is($attachment->{content_type}, $t->{args}->{content_type}, $rpc->TYPE . ": Attachment $id content type is correct"); } if ($rpc->isa('QA::RPC::JSONRPC')) { # We encoded data in pre_call(), so we have to restore it to its original content. $t->{args}->{data} = decode_base64($t->{args}->{data}); $attachment->{data} = decode_base64($attachment->{data}); } is($attachment->{data}, $t->{args}->{data}, $rpc->TYPE . ": Attachment $id data is correct"); } }