APISchema

 view release on metacpan or  search on metacpan

eg/bmi.psgi  view on Meta::CPAN

        enable "APISchema::ResponseValidator", schema => $schema;
        enable "APISchema::RequestValidator",  schema => $schema;

        Plack::App::APISchema::MockServer->new(
            schema => $schema,
        )->to_app;
    };
    mount '/doc.md' => sub {
        my $generator = APISchema::Generator::Markdown->new;
        my $content = $generator->format_schema($schema);
        [200, ['Content-Type' => 'text/plain; charset=utf-8;'], [$content]];
    };

    mount '/' => $app;
}

__END__

=encoding utf-8

=head1 NAME

lib/APISchema/Validator.pm  view on Meta::CPAN

sub for_response {
    my $class = shift;
    return $class->_new(@_, fetch_resource_method => 'canonical_response_resource');
}

sub _valid_result { APISchema::Validator::Result->new_valid(@_) }
sub _error_result { APISchema::Validator::Result->new_error(@_) }

sub _resolve_encoding {
    my ($content_type, $encoding_spec) = @_;
    # TODO handle charset?
    $content_type = $content_type =~ s/\s*;.*$//r;
    $encoding_spec //= DEFAULT_ENCODING_SPEC;

    if (ref $encoding_spec) {
        $encoding_spec = $encoding_spec->{$content_type};
        return ( undef, { message => "Wrong content-type: $content_type" } )
            unless $encoding_spec;
    }

    my $method = $encoding_spec;

lib/Plack/App/APISchema/Document.pm  view on Meta::CPAN

                | Text::Markdown::Hoedown::HOEDOWN_EXT_AUTOLINK
                | Text::Markdown::Hoedown::HOEDOWN_EXT_FENCED_CODE
                | Text::Markdown::Hoedown::HOEDOWN_EXT_NO_INTRA_EMPHASIS
            )
    );

    my $renderer = Text::MicroTemplate::DataSection->new(package => ref $self);
    my $title = $self->schema->title || '';
    my $html = $renderer->render_mt('template.mt', $title, $body);

    return [200, ['Content-Type' => 'text/html; charset=utf-8'], [encode_utf8 $html]];
}

1;
__DATA__
@@ template.mt
? my ($title, $body) = @_;
<!DOCTYPE html>
<html>
  <head>
    <title><?= $title ?></title>

lib/Plack/App/APISchema/MockServer.pm  view on Meta::CPAN

use APISchema::Generator::Markdown::ExampleFormatter;

sub call {
    my ($self, $env) = @_;

    my $req = Plack::Request->new($env);

    my ($matched, $router_simple_route) = $self->router->routematch($env);

    unless ($matched) {
        return [404, ['Content-Type' => 'text/plain; charset=utf-8'], ['not found']];
    }

    my $root = $self->schema->get_resource_root;

    my $route = $self->schema->get_route_by_name($router_simple_route->name);

    my $default_code = $route->default_responsible_code;
    my $response_resource = $route->canonical_response_resource($root, [
        $default_code
    ]);

    my $resolver = APISchema::Generator::Markdown::ResourceResolver->new(schema => $root);

    my $formatter = APISchema::Generator::Markdown::ExampleFormatter->new(
        resolver => $resolver,
        spec     => $response_resource,
    );

    # TODO: serve all headers defined in example
    # TODO: format body with encoding
    return [$default_code, ['Content-Type' => 'application/json; charset=utf-8'], [encode_utf8($formatter->body)]];
}

sub router {
    my ($self) = @_;

    return $self->{router} if $self->{router};

    my $generator = APISchema::Generator::Router::Simple->new;
    $self->{router} = $generator->generate_router($self->schema);
}

t/Plack-App-APISchema-Document.t  view on Meta::CPAN


sub serve_document : Tests {
     my $schema = t::test::fixtures::prepare_bmi;
     my $app = Plack::App::APISchema::Document->new(schema => $schema)->to_app;

     subtest 'when valid request' => sub {
         test_psgi $app => sub {
             my $server = shift;
             my $res = $server->(GET '/');
             is $res->code, 200;
             is $res->header('content-type'), 'text/html; charset=utf-8';
             like $res->content, qr{<h3 id="toc_8"><a name="resource-figure"></a> <code>figure</code> : <code>object</code></h3>};
             done_testing;
         }
     };
}

sub mojibake : Tests {
    my $schema = t::test::fixtures::prepare_author;
    my $app = Plack::App::APISchema::Document->new(schema => $schema)->to_app;

     subtest 'when valid request' => sub {
         test_psgi $app => sub {
             my $server = shift;
             my $res = $server->(GET '/');
             is $res->code, 200;
             is $res->header('content-type'), 'text/html; charset=utf-8';
             like $res->content, qr{td>著者</td>};
             done_testing;
         }
     };
}

sub inheritable : Tests {
    my $schema = t::test::fixtures::prepare_bmi;
    my $app = t::test::InheritedDocument->new(schema => $schema)->to_app;

    subtest 'Document is inheritable' => sub {
        test_psgi $app => sub {
            my $server = shift;
            my $res = $server->(GET '/');
            is $res->code, 200;
            is $res->header('content-type'), 'text/html; charset=utf-8';
            like $res->content, qr{pink};
            done_testing;
        };
    };
}

t/Plack-App-APISchema-MockServer.t  view on Meta::CPAN


sub serve_document_bmi : Tests {
     my $schema = t::test::fixtures::prepare_bmi;
     my $app = Plack::App::APISchema::MockServer->new(schema => $schema)->to_app;

     subtest 'when valid request' => sub {
         test_psgi $app => sub {
             my $server = shift;
             my $res = $server->(POST '/bmi');
             is $res->code, 200;
             is $res->header('content-type'), 'application/json; charset=utf-8';
             is $res->content, q!{"value":19.5}!;
         }
     };

     subtest 'when invalid request' => sub {
         test_psgi $app => sub {
             my $server = shift;
             my $res = $server->(POST '/notfound');
             is $res->code, 404;
             is $res->header('content-type'), 'text/plain; charset=utf-8';
             is $res->content, q!not found!;
         }
     };
}

sub when_encoding_is_specified : Tests {
    my $schema = t::test::fixtures::prepare_bmi;
    $schema->register_route(
        method => 'POST',
        route => '/bmi_force_json',

t/Plack-App-APISchema-MockServer.t  view on Meta::CPAN

        response_resource => {
            encoding => 'json',
            body => 'bmi',
        },
    );
    my $app = Plack::App::APISchema::MockServer->new(schema => $schema)->to_app;
    test_psgi $app => sub {
        my $server = shift;
        my $res = $server->(POST '/bmi_force_json');
        is $res->code, 200;
        is $res->header('content-type'), 'application/json; charset=utf-8';
        is $res->content, q!{"value":19.5}!;
    }
}

sub with_wide_character : Tests {
    my $schema = t::test::fixtures::prepare_author;
    $schema->register_route(
        method => 'GET',
        route => '/author',
        response_resource => {

t/Plack-App-APISchema-MockServer.t  view on Meta::CPAN

            body => 'author',
        },
    );

    my $app = Plack::App::APISchema::MockServer->new(schema => $schema)->to_app;

    test_psgi $app => sub {
        my $server = shift;
        my $res = $server->(GET '/author');
        is $res->code, 200;
        is $res->header('content-type'), 'application/json; charset=utf-8';
        is $res->content, q!{"author_name":"著者"}!;
    };
}

sub one_of : Tests {
    my $schema = t::test::fixtures::prepare_bmi;
    $schema->register_resource(maybe_bmi => {
        oneOf => [
            {
                type => 'object',

t/Plack-App-APISchema-MockServer.t  view on Meta::CPAN

            body => 'maybe_bmi',
        },
    );

    my $app = Plack::App::APISchema::MockServer->new(schema => $schema)->to_app;

    test_psgi $app => sub {
        my $server = shift;
        my $res = $server->(GET '/maybe_bmi');
        is $res->code, 200;
        is $res->header('content-type'), 'application/json; charset=utf-8';
        is $res->content, q!{"value":19.5}!;
    };
}

sub status_201 : Tests {
    my $schema = t::test::fixtures::prepare_bmi;
    $schema->register_route(
        method => 'PUT',
        route => '/put_bmi',
        request_resource => {

t/Plack-Middleware-APISchema-RequestValidator.t  view on Meta::CPAN

            is $res->code, 200;
            done_testing;
        }
    };

    subtest 'when valid utf8 request' => sub {
        test_psgi $middleware => sub {
            my $server = shift;
            my $res = $server->(
                POST '/bmi',
                Content_Type => 'application/json; charset=UTF-8',
                Content => encode_json({weight => 50, height => 1.6}),
            );
            is $res->code, 200;
            done_testing;
        }
    };

    subtest 'when invalid request' => sub {
        test_psgi $middleware => sub {
            my $server = shift;

t/Plack-Middleware-APISchema-ResponseValidator.t  view on Meta::CPAN

    my $schema = t::test::fixtures::prepare_user;
    $schema->register_route(
        method => 'GET',
        route => '/user',
        response_resource => {
            body => 'user',
        },
    );
    my $middleware = Plack::Middleware::APISchema::ResponseValidator->new(schema => $schema);
    $middleware->wrap(sub {
        [200, [ 'Content-Type' => 'application/json; charset=utf-8' ], [ encode_json({ first_name => 'Bill', last_name => []}) ]  ]
    });

    subtest 'invalid response with utf8' => sub {
        test_psgi $middleware => sub {
            my $server = shift;
            my $res = $server->(GET '/user');
            is $res->code, 500;
            cmp_deeply $res->content, json({
                body => {
                    attribute => "Valiemon::Attributes::Type",



( run in 0.667 second using v1.01-cache-2.11-cpan-49f99fa48dc )