Catalyst-Plugin-JSONRPC-Server

 view release on metacpan or  search on metacpan

t/plugin-hardening.t  view on Meta::CPAN

use v5.36;
use Test::More;
use Test::Fatal;
use Catalyst::Plugin::JSONRPC::Server;
use Catalyst::Plugin::JSONRPC::Server::Dispatcher;

# --- minimal stub context (no Catalyst), with an optional ->config ----------
package StubResponse {
    sub new          { bless {}, shift }
    sub status       { my $s = shift; $s->{status}       = shift if @_; $s->{status} }
    sub content_type { my $s = shift; $s->{content_type} = shift if @_; $s->{content_type} }
    sub body         { my $s = shift; $s->{body}         = shift if @_; $s->{body} }
}
package StubRequest {
    sub new  { my ( $class, $body ) = @_; bless { body => $body }, $class }
    sub body { $_[0]{body} }
}
package StubContext {
    our @ISA = ('Catalyst::Plugin::JSONRPC::Server');
    sub new {
        my ( $class, %args ) = @_;
        bless {
            response => StubResponse->new,
            request  => $args{request},
            ( exists $args{config} ? ( _config => $args{config} ) : () ),
        }, $class;
    }
    sub response { $_[0]{response} }
    sub request  { $_[0]{request} }
    # Only present when a config was supplied, so we also exercise the
    # can('config') guard in the plugin when it is absent.
    sub config   { $_[0]{_config} }
}
# --------------------------------------------------------------------------

# --- I3: handlers registered on one context must NOT leak into another ------
# On the old per-app %DISPATCHER (keyed by app class) a fresh context would see
# a handler a previous context registered; the per-request dispatcher fixes it.
{
    my $c1 = StubContext->new;
    $c1->jsonrpc_register( secret => sub ($p) { 'leaked' } );
    $c1->jsonrpc_dispatch('{"jsonrpc":"2.0","method":"secret","params":[],"id":1}');

    my $c2 = StubContext->new;    # a brand-new request
    my $data = $c2->jsonrpc_dispatch('{"jsonrpc":"2.0","method":"secret","id":2}');
    is( $data->{error}{code}, -32601,
        'a handler registered on one context does not leak into another (I3)' );
}

# --- I4: the nothing-to-send status is configurable (202 for the MCP transport)
{
    my $c = StubContext->new;
    my $d = Catalyst::Plugin::JSONRPC::Server::Dispatcher->new;
    $d->register( note => sub ($p) { 'x' } );
    my $none = $c->jsonrpc_dispatch_with(
        $d, '{"jsonrpc":"2.0","method":"note","params":[1]}', 202 );
    is( $none, undef, 'notification still returns undef' );
    is( $c->response->status, 202,
        'empty-response status honours the caller-supplied 202 (I4)' );
}
# ...and the default is still 204 when not overridden.
{
    my $c = StubContext->new;



( run in 0.928 second using v1.01-cache-2.11-cpan-54e63673c56 )