APISchema
view release on metacpan or search on metacpan
t/Plack-Middleware-APISchema-ResponseValidator.t view on Meta::CPAN
package t::Plack::Middleware::APISchema::ResponseValidator;
use lib '.';
use t::test;
use t::test::fixtures;
use Plack::Test;
use Plack::Request;
use HTTP::Request::Common;
use JSON::XS qw(encode_json);
sub _require : Test(startup => 1) {
my ($self) = @_;
use_ok 'Plack::Middleware::APISchema::ResponseValidator';
}
sub instantiate : Tests {
my $schema = APISchema::Schema->new;
my $middleware = Plack::Middleware::APISchema::ResponseValidator->new(schema => $schema);
isa_ok $middleware, 'Plack::Middleware::APISchema::ResponseValidator';
is $middleware->schema, $schema;
isa_ok $middleware->router, 'Router::Simple';
}
sub response_validator : Tests {
my $schema = t::test::fixtures::prepare_bmi;
$schema->register_route(
method => 'POST',
route => '/bmi_strict',
response_resource => {
encoding => { 'application/json' => 'json' },
body => 'bmi',
},
);
$schema->register_route(
method => 'POST',
route => '/bmi_force_json',
response_resource => {
encoding => 'json',
body => 'bmi',
},
);
$schema->register_resource(bmi_header => {
type => 'object',
properties => {
'x_value' => { type => 'number' },
},
required => ['x_value'],
});
$schema->register_route(
method => 'POST',
route => '/bmi_by_header',
response_resource => {
header => 'bmi_header',
},
);
my $content_type;
my $json;
my $middleware = Plack::Middleware::APISchema::ResponseValidator->new(schema => $schema);
my $header = [];
$middleware->wrap(sub {
[200, [ 'Content-Type' => $content_type, @$header ], [ $json ] ]
});
subtest 'when valid response' => sub {
test_psgi $middleware => sub {
$content_type = 'application/json';
$json = encode_json({value => 19.5});
$header = [];
my $server = shift;
my $res = $server->(POST '/bmi');
is $res->code, 200;
done_testing;
}
};
subtest 'when invalid response' => sub {
test_psgi $middleware => sub {
$content_type = 'application/json';
$json = encode_json({value => 'aaa'});
$header = [];
my $server = shift;
my $res = $server->(POST '/bmi');
is $res->code, 500;
is $res->header('X-Error-Cause'), 'Plack::Middleware::APISchema::ResponseValidator+Valiemon';
cmp_deeply $res->content, json({
body => {
attribute => "Valiemon::Attributes::Type",
position => '/$ref/properties/value/type',
expected => $schema->get_resource_by_name('bmi')->definition->{properties}->{value},
actual => 'aaa',
message => "Contents do not match resource 'bmi'",
encoding => 'json',
},
});
done_testing;
}
};
subtest 'when wrong content-type' => sub {
test_psgi $middleware => sub {
$content_type = 'text/plain';
$json = encode_json({value => 19.5});
$header = [];
my $server = shift;
my $res = $server->(POST '/bmi');
is $res->code, 500;
is $res->header('X-Error-Cause'), 'Plack::Middleware::APISchema::ResponseValidator+Valiemon';
cmp_deeply $res->content, json({
body => { message => "Wrong content-type: text/plain" },
});
done_testing;
}
};
subtest 'when response is not a JSON' => sub {
test_psgi $middleware => sub {
$content_type = 'application/json';
$json = 'aaa';
$header = [];
my $server = shift;
my $res = $server->(POST '/bmi');
is $res->code, 500;
is $res->header('X-Error-Cause'), 'Plack::Middleware::APISchema::ResponseValidator+Valiemon';
cmp_deeply $res->content, json({
body => {
message => "Failed to parse json",
encoding => 'json',
},
});
done_testing;
}
};
subtest 'when content-type is incorrect' => sub {
test_psgi $middleware => sub {
$content_type = 'application/x-www-form-urlencoded';
$json = encode_json({value => 19.5});
$header = [];
my $server = shift;
my $res = $server->(POST '/bmi');
is $res->code, 500;
is $res->header('X-Error-Cause'), 'Plack::Middleware::APISchema::ResponseValidator+Valiemon';
cmp_deeply $res->content, json({
body => {
attribute => 'Valiemon::Attributes::Required',
position => '/$ref/required',
message => "Contents do not match resource 'bmi'",
encoding => 'url_parameter',
actual => {
'{"value":19.5}' => undef,
},
expected => $schema->get_resource_by_name('bmi')->definition,
},
});
done_testing;
}
};
subtest 'when content-type is incorrect with forced encoding' => sub {
test_psgi $middleware => sub {
$content_type = 'application/x-www-form-urlencoded';
$json = encode_json({value => 19.5});
$header = [];
my $server = shift;
my $res = $server->(POST '/bmi_force_json');
is $res->code, 200;
done_testing;
}
};
subtest 'when content-type is incorrect with strict content-type check' => sub {
test_psgi $middleware => sub {
$content_type = 'application/x-www-form-urlencoded';
$json = encode_json({value => 19.5});
my $server = shift;
( run in 1.149 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )