Dancer-Plugin-RPC-RESTISH

 view release on metacpan or  search on metacpan

t/225-register-restish.t  view on Meta::CPAN

#! perl -w
use strict;
use lib 't/lib';

use Test::More;

use Dancer qw/:syntax !pass/;

use Dancer::Plugin::RPC::RESTISH;
use Dancer::RPCPlugin::CallbackResult;
use Dancer::RPCPlugin::DispatchItem;
use Dancer::RPCPlugin::ErrorResponse;

use Dancer::Test;

{
    note("default publish == 'config'");
    set(plugins => {
        'RPC::RESTISH' => {
            '/endpoint' => {
                'TestProject::SystemCalls' => {
                    'GET@ping'    => 'do_ping',
                    'GET@version' => 'do_version',
                },
            },
        }
    });
    set(encoding => 'utf-8');
    restish '/endpoint' => { };

    route_exists([GET => '/endpoint/ping'],    "GET /endpoint/ping registered");
    route_exists([GET => '/endpoint/version'], "GET /endpoint/version registered");

    my $response = dancer_response(
        GET => '/endpoint/ping',
    );

    my $ping = from_json('{"response": true}');
    if (JSON->VERSION >= 2.90) {
        my $t = 1;
        $ping->{response} = bless \$t, 'JSON::PP::Boolean';
    }

    is_deeply(
        from_json($response->{content}),
        $ping,
        "GET /endpoint/ping"
    ) or diag(explain($response));
}

{
    note("publish is code that returns the dispatch-table");
    restish '/endpoint2' => {
        publish => sub {
            eval { require TestProject::SystemCalls; };
            error("Cannot load: $@") if $@;
            return {
                'GET@version' => dispatch_item(
                    code    => TestProject::SystemCalls->can('do_version'),
                    package => 'TestProject::SystemCalls',
                ),
            };
        },
        callback => sub { return callback_success(); },
    };

    route_exists([GET => '/endpoint2/version'], "GET /endpoint2/version registered");

    my $response = dancer_response(
        GET => '/endpoint2/version',
    );

    is_deeply(
        from_json($response->{content}),
        { software_version => $TestProject::SystemCalls::VERSION },
        "GET /endpoint2/version"
    );
}

{
    note("callback fails");
    restish '/fail1' => {
        publish => sub {
            eval { require TestProject::SystemCalls; };
            error("Cannot load: $@") if $@;
            return {
                'GET@version' => dispatch_item(
                    code    => TestProject::SystemCalls->can('do_version'),
                    package => 'TestProject::SystemCalls',
                ),
            };
        },
        callback => sub {
            return callback_fail(
                error_code    => -32601,
                error_message => "Force callback error",
            );
        },
    };

    route_exists([GET => '/fail1/version'], "GET /fail1/version registered");

    my $response = dancer_response(
        GET => '/fail1/version',
    );

    is($response->{status}, 403, "callback http-status 403") or diag(explain($response));

    my $result = $response->header('content-type') eq 'application/json'
        ? from_json($response->{content})
        : $response->{content};
    is_deeply(
        $result,
        {
            error_code    => -32601,
            error_message => "Force callback error",
            error_data    => { },
        },
        "GET /fail1/version (callback_fail)"
    ) or diag(explain($response));
}

{
    note("callback dies");
    restish '/fail2' => {
        publish => sub {
            eval { require TestProject::SystemCalls; };
            error("Cannot load: $@") if $@;
            return {
                'GET@version' => dispatch_item(
                    code    => \&TestProject::SystemCalls::do_version,
                    package => 'TestProject::SystemCalls',
                ),
            };
        },
        callback => sub {
            die "terrible death\n";
        },
    };

    route_exists([GET => '/fail2/version'], "/fail2/version registered");

    my $response = dancer_response(
        GET => '/fail2/version',
    );
    is($response->{status}, 500, "callback http-status 500") or diag(explain($response));

    my $result = $response->header('content-type') eq 'application/json'
        ? from_json($response->{content})
        : $response->{content};
    is_deeply(
        $result,
        {
            error_code    => -32500,
            error_message => "terrible death\n",
            error_data    => { },
        },
        "GET /endpoint_fail2/version (callback dies)"
    ) or diag(explain($result));
}

{
    note("callback returns unknown object");
    restish '/fail3' => {
        publish => sub {
            eval { require TestProject::SystemCalls; };
            error("Cannot load: $@") if $@;
            return {
                'GET@version' => dispatch_item(
                    code    => \&TestProject::SystemCalls::do_version,
                    package => 'TestProject::SystemCalls',
                ),
            };
        },
        callback => sub {
            bless {easter => 'egg'}, 'SomeRandomClass';
        },
        code_wrapper => sub {
            return 'pang';
        },
    };

    route_exists([GET => '/fail3/version'], "/fail3/ registered");

    my $response = dancer_response(
        GET => '/fail3/version',
    );
    is($response->{status}, 400, "callback http-status 500") or diag(explain($response));

    my $result = from_json($response->{content});
    is_deeply(
        $result,
        {
            error_code    => -32603,
            error_message => "Internal error: 'callback_result' wrong class SomeRandomClass",
            error_data    => {},
        },
        "GET /fail3/version (callback wrong class)"
    ) or diag(explain($response));
}

{
    note("callback checks \$Dancer::RPCPlugin::ROUTE_INFO");
    restish '/callback' => {
        publish => sub {
            eval { require TestProject::SystemCalls; };
            error("Cannot load: $@") if $@;
            return {
                'GET@version/:api_version' => dispatch_item(
                    code    => \&TestProject::SystemCalls::do_version,
                    package => 'TestProject::SystemCalls',
                ),
            };
        },
        callback => sub {
            my ($request, $method_name, $method_args) = @_;

            # Access only for 'small-letter-v' with a version



( run in 0.336 second using v1.01-cache-2.11-cpan-c966e8aa7e8 )