Dancer2-Plugin-RPC-RESTISH

 view release on metacpan or  search on metacpan

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

#! perl -I. -w
use t::Test::abeltje;

use Dancer2;

use Dancer2::Plugin::RPC::RESTISH;
use Dancer2::RPCPlugin::CallbackResultFactory;
use Dancer2::RPCPlugin::DispatchItem;
use Dancer2::RPCPlugin::ErrorResponse;

use HTTP::Request;
use Plack::Test;

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

    restish '/endpoint' => { };

    my $tester = Plack::Test->create(main->to_app());
    my $response = $tester->request(
        HTTP::Request->new(GET => '/endpoint/ping')
    );

    my $ping = from_json('{"response": true}');

    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' => Dancer2::RPCPlugin::DispatchItem->new(
                    code    => TestProject::SystemCalls->can('do_version'),
                    package => 'TestProject::SystemCalls',
                ),
            };
        },
        callback => sub { return callback_success(); },
    };

    my $tester = Plack::Test->create(main->to_app());
    my $response = $tester->request(
        HTTP::Request->new(GET => '/endpoint2/version')
    );

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

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

    my $tester = Plack::Test->create(main->to_app());

    my $response = $tester->request(
        HTTP::Request->new(GET => '/fail1/version')
    );

    is($response->code, 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' => Dancer2::RPCPlugin::DispatchItem->new(
                    code    => \&TestProject::SystemCalls::do_version,
                    package => 'TestProject::SystemCalls',
                ),
            };
        },
        callback => sub {
            die "terrible death\n";
        },
    };

    my $tester = Plack::Test->create(main->to_app());

    my $response = $tester->request(
        HTTP::Request->new(GET => '/fail2/version')
    );
    is($response->code, 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' => Dancer2::RPCPlugin::DispatchItem->new(
                    code    => \&TestProject::SystemCalls::do_version,
                    package => 'TestProject::SystemCalls',
                ),
            };
        },
        callback => sub {
            bless {easter => 'egg'}, 'SomeRandomClass';
        },
        code_wrapper => sub {
            return 'pang';
        },
    };

    my $tester = Plack::Test->create(main->to_app());

    my $response = $tester->request(
        HTTP::Request->new(GET => '/fail3/version')
    );
    is($response->code, 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 \$Dancer2::RPCPlugin::ROUTE_INFO");
    restish '/callback' => {
        publish => sub {
            eval { require TestProject::SystemCalls; };
            error("Cannot load: $@") if $@;
            return {
                'GET@version/:api_version' => Dancer2::RPCPlugin::DispatchItem->new(
                    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.954 second using v1.01-cache-2.11-cpan-2ed5026b665 )