The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Test::TCM::Role::API - Role to test PSGI-based JSON API using Test::Class::Moose.

SYNOPSIS

    package TestsFor::MyApp::Controller::API::v1::Some::Thing

    use Test::Class::Moose;
    with qw(
        Test::TCM::Role::API
    );

    sub _api_route_prefix { '/api/v1' }

    sub test_some_route ($test, $) {

        # Calls "GET /api/v1/character"
        $test->api_ok(
            'List characters',
            [GET => '/character'],
            {
                status       => HTTP_OK,
                json_content => {
                    superhashof(
                        {
                            attributes =>
                              { map { $_ => ignore() } qw(id name created) },
                        }
                    )
                },
            }
        );

        $test->api_ok(
            'Create character',
            [
                POST => '/character' => {
                    name    => 'Player 1',
                    user_id => 12345,
                }
            ],
            {
                status       => HTTP_OK,
                json_content => { success => 1 },
            }
        );
    }

REQUIRED METHODS

psgi_app

PSGI application we're testing.

ATTRIBUTES

api_client

PSGI-compatible API client to use. Built automatically using psgi_app method.

PRIVATE METHODS THAT CAN BE OVERRIDDEN

_api_content_type

Returns content type for this API, default: application/vnd.api+json.

_api_headers

Returns a hash of headers to add to $test->mech, defaults to ( Accept => _api_content_type() )

_api_route_prefix

Common prefix for all API requests. Defaults to the empty string.

_before_request_hook($request)

Method that is called right before request is made. Gets a complete HTTP::Request object as the only argument. You can inspect / modify this request as needed - e.g. to add additional authorization headers to it.

METHODS

api_ok($title, \@request_args, \%expected)

    In: $title - (sub)test title
        \@request_args - request data, 3-elements array of:
            $method - HTTP method
            $route - route to call
            \%params - URL query params (for GET) or JSON data (for other
            request types)
        \%expected - hash of expected parameters with the following fields
            status - HTTP status code; defaults to any successful code
            json_content - reference to a structure we expect, to be passed to
            C<Test::Deep::cmp_deeply> (so C<Test::Deep>'s functions can be used
            to skip / ignore some methods in it).

Perform API $method request on the $route and test its output against %expected values.

If _api_route_prefix() is implemented in the consuming class, the value it returns gets prepended to the route before request is performed.

AUTHOR

Ilya Chesnokov chesnokov@cpan.org.

LICENSE

Under the same terms as Perl itself.

CREDITS

Many thanks to the following people and organizations:

Sam Kington cpan@illuminated.co.uk

For the idea and the initial implementation.

All Around the World SASU https://allaroundtheworld.fr

For sponsoring this rewrite and publication.