Files
zonemaster.es/zonemaster-backend/t/rpc_validation.t

243 lines
6.8 KiB
Perl
Raw Normal View History

use strict;
use warnings;
use 5.14.2;
use utf8;
use Test::More tests => 30;
use Test::NoWarnings;
use Cwd;
use File::Temp qw[tempdir];
use Zonemaster::Backend::Config;
use Zonemaster::Backend::RPCAPI;
use JSON::Validator::Joi "joi";
use JSON::PP;
###
### Setup
###
my $tempdir = tempdir( CLEANUP => 1 );
my $cwd = cwd();
my $config = Zonemaster::Backend::Config->parse( <<EOF );
[DB]
engine = SQLite
[SQLITE]
database_file = $tempdir/zonemaster.sqlite
[PUBLIC PROFILES]
test = $cwd/t/test_profile.json
EOF
my $rpcapi = Zonemaster::Backend::RPCAPI->new(
{
dbtype => $config->DB_engine,
config => $config,
}
);
###
### JSONRPC request object construction helper
###
sub jsonrpc
{
my ($method, $params, $force_undef) = @_;
my $object = {
jsonrpc => '2.0',
id => 'testing',
method => $method
};
if (defined $params or $force_undef) {
$object->{params} = $params;
}
return $object;
}
###
### JSONRPC error response construction helpers
###
sub jsonrpc_error
{
my ($message, $code, $data, $id) = @_;
my $object = {
jsonrpc => '2.0',
id => $id,
error => {
message => $message,
code => $code
}
};
$object->{error}{data} = $data if defined $data;
return $object;
}
sub error_bad_jsonrpc
{
my ($data) = @_;
jsonrpc_error('The JSON sent is not a valid request object.', '-32600', $data, undef);
}
sub error_missing_params
{
jsonrpc_error("Missing 'params' object", '-32602', undef, 'testing');
}
sub error_bad_params
{
my ($messages) = @_;
my @data;
while (@$messages) {
my $path = shift @$messages;
my $message = shift @$messages;
push @data, { path => $path, message => $message };
}
jsonrpc_error('Invalid method parameter(s).', '-32602', \@data, 'testing');
}
sub no_error
{
return '';
}
###
### Test wrapper functions
###
sub test_validation
{
my ($input, $output, $message) = @_;
my $res = $rpcapi->jsonrpc_validate($input);
is_deeply($res, $output, $message) or diag(encode_json($res));
}
###
### The tests themselves
###
test_validation undef,
error_bad_jsonrpc('/: Expected object - got null.'),
"Sending undef is an error";
test_validation JSON::PP::false,
error_bad_jsonrpc('/: Expected object - got boolean.'),
"Sending a boolean is an error";
test_validation -1,
error_bad_jsonrpc('/: Expected object - got number.'),
"Sending a number is an error";
test_validation "hello",
error_bad_jsonrpc('/: Expected object - got string.'),
"Sending a string is an error";
test_validation [qw(a b c)],
error_bad_jsonrpc('/: Expected object - got array.'),
"Sending an array is an error";
test_validation {},
error_bad_jsonrpc('/jsonrpc: Missing property. /method: Missing property.'),
"Sending an empty object is an error";
test_validation { jsonrpc => '2.0' },
error_bad_jsonrpc('/method: Missing property.'),
"Sending an incomplete object is an error";
test_validation { jsonrpc => '2.0', method => 'system_versions' },
error_bad_jsonrpc(''),
"Sending an object with no ID is an error";
test_validation { jsonrpc => '2.0', method => 'system_versions', id => JSON::PP::false },
error_bad_jsonrpc('/id: Expected null/number/string - got boolean.'),
"Sending an object whose ID is a boolean is an error";
test_validation { jsonrpc => '2.0', method => 'system_versions', id => [qw(a b c)] },
error_bad_jsonrpc('/id: Expected null/number/string - got array.'),
"Sending an object whose ID is an array is an error";
test_validation { jsonrpc => '2.0', method => 'system_versions', id => { a => 1 } },
error_bad_jsonrpc('/id: Expected null/number/string - got object.'),
"Sending an object whose ID is an object is an error";
test_validation jsonrpc("job_status"),
error_missing_params(),
"Calling job_status without parameters is an error";
test_validation jsonrpc("job_status", undef, 1),
error_bad_params(["/" => "Expected object - got null."]),
"Passing null as parameter to job_status is an error";
test_validation jsonrpc("job_status", JSON::PP::false),
error_bad_params(["/" => "Expected object - got boolean."]),
"Passing boolean as parameter to job_status is an error";
test_validation jsonrpc("job_status", 1),
error_bad_params(["/" => "Expected object - got number."]),
"Passing number as parameter to job_status is an error";
test_validation jsonrpc("job_status", "hello"),
error_bad_params(["/" => "Expected object - got string."]),
"Passing string as parameter to job_status is an error";
test_validation jsonrpc("job_status", [qw(a b c)]),
error_bad_params(["/" => "Expected object - got array."]),
"Passing array as parameter to job_status is an error";
test_validation jsonrpc("job_status", {}),
error_bad_params(["/job_id" => "Missing property"]),
"Passing empty object as parameter to job_status is an error";
test_validation jsonrpc("job_status", { job_id => 'this_will_definitely_never_ever_exist' }),
error_bad_params(["/job_id" => 'String does not match (?^u:^[0-9a-f]{16}$).']),
"Calling job_status with a bad job_id is an error";
test_validation jsonrpc("job_status", { job_id => '0123456789abcdef', data => "something" }),
error_bad_params(["/" => "Properties not allowed: data."]),
"Calling job_status with unknown parameters is an error";
test_validation jsonrpc("job_status", { job_id => '0123456789abcdef' }),
no_error,
"Calling job_status with a good job_id succeeds";
test_validation jsonrpc("system_versions"),
no_error,
"Calling system_versions with no parameters is OK";
test_validation jsonrpc("system_versions", undef, 1),
error_bad_params(["/" => "Expected object - got null."]),
"Passing null as parameter to system_versions is an error";
test_validation jsonrpc("system_versions", JSON::PP::false),
error_bad_params(["/" => "Expected object - got boolean."]),
"Passing number as parameter to system_versions is an error";
test_validation jsonrpc("system_versions", -1),
error_bad_params(["/" => "Expected object - got number."]),
"Passing number as parameter to system_versions is an error";
test_validation jsonrpc("system_versions", "hello"),
error_bad_params(["/" => "Expected object - got string."]),
"Passing string as parameter to system_versions is an error";
test_validation jsonrpc("system_versions", [qw(a b c)]),
error_bad_params(["/" => "Expected object - got array."]),
"Passing array as parameter to system_versions is an error";
test_validation jsonrpc("system_versions", { data => "something" }),
error_bad_params(["/" => "Properties not allowed: data."]),
"Calling system_versions with unrecognized parameter is an error";
test_validation jsonrpc("system_versions", {}),
no_error,
"Calling system_versions with empty object succeeds";