Catalyst-Runtime

 view release on metacpan or  search on metacpan

t/aggregate/live_component_controller_action_chained.t  view on Meta::CPAN

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/../lib";

our $iters;

BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }

use Test::More;
use URI;
use URI::QueryParam;
use Catalyst::Test 'TestApp';

if ( $ENV{CAT_BENCHMARK} ) {
    require Benchmark;
    Benchmark::timethis( $iters, \&run_tests );
}
else {
    for ( 1 .. $iters ) {
        run_tests($_);
    }
}

sub run_tests {
    my ($run_number) = @_;

    #
    #   This is a simple test where the parent and child actions are
    #   within the same controller.
    #
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained->foo
          TestApp::Controller::Action::Chained->endpoint
          TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/chained/foo/1/end/2'), 'chained + local endpoint' );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, '1; 2', 'Content OK' );
    }

    #
    #   This makes sure the above isn't found if the argument for the
    #   end action isn't supplied.
    #
    {
        my $expected = undef;

        ok( my $response = request('http://localhost/chained/foo/1/end'),
            'chained + local endpoint; missing last argument' );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->code, 500, 'Status OK' );
    }

    #
    #   Tests the case when the child action is placed in a subcontroller.
    #
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained->foo
          TestApp::Controller::Action::Chained::Foo->spoon
          TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/chained/foo/1/spoon'), 'chained + subcontroller endpoint' );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, '1; ', 'Content OK' );
    }

    #
    #   Tests if the relative specification (e.g.: Chained('bar') ) works
    #   as expected.
    #
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained->bar
          TestApp::Controller::Action::Chained->finale
          TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/chained/bar/1/spoon'), 'chained + relative endpoint' );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, '; 1, spoon', 'Content OK' );
    }

    #
    #   Just a test for multiple arguments.
    #
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained->foo2
          TestApp::Controller::Action::Chained->endpoint2
          TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/chained/foo2/10/20/end2/15/25'),
            'chained + local (2 args each)' );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, '10, 20; 15, 25', 'Content OK' );
    }

    #
    #   The first three-chain test tries to call the action with :Args(1)
    #   specification. There's also a one action with a :CaptureArgs(1)
    #   attribute, that should not be dispatched to.
    #
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained->one_end
          TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/chained/one/23'),
            'three-chain (only first)' );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, '; 23', 'Content OK' );
    }

    #
    #   This is the second three-chain test, it goes for the action that
    #   handles "/one/$cap/two/$arg1/$arg2" paths. Should be the two action
    #   having :Args(2), not the one having :CaptureArgs(2).
    #
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained->one
          TestApp::Controller::Action::Chained->two_end
          TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/chained/one/23/two/23/46'),
            'three-chain (up to second)' );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, '23; 23, 46', 'Content OK' );
    }

    #
    #   Last of the three-chain tests. Has no concurrent action with :CaptureArgs
    #   and is more thought to simply test the chain as a whole and the 'two'
    #   action specifying :CaptureArgs.
    #

t/aggregate/live_component_controller_action_chained.t  view on Meta::CPAN

    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained->chain_die_a
          TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/chained/chain_die/1/end/2'),
            "Break a chain in the middle" );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, 'FATAL ERROR: Caught exception in TestApp::Controller::Action::Chained->chain_die_a "die in the middle of a chain"', 'Content OK' );
    }

    #
    #   Tests that an uri_for to a chained root index action
    #   returns the right value.
    #
    {
        ok( my $response = request(
            'http://localhost/action/chained/to_root' ),
            'uri_for with chained root action as arg' );
        like( $response->content,
            qr(URI:https?://[^/]+/),
            'Correct URI generated' );
    }

    #
    #   Test interception of recursive chains. This test was added because at
    #   one point during the :Chained development, Catalyst used to hang on
    #   recursive chains.
    #
    {
        eval { require 'TestAppChainedRecursive.pm' };
        if ($run_number == 1) {
            ok( ! $@, "Interception of recursive chains" );
        }
        else { pass( "Interception of recursive chains already tested" ) }
    }

    #
    #   Test failure of absolute path part arguments.
    #
    {
        eval { require 'TestAppChainedAbsolutePathPart.pm' };
        if ($run_number == 1) {
            like( $@, qr(foo/foo),
                "Usage of absolute path part argument emits error" );
        }
        else { pass( "Error on absolute path part arguments already tested" ) }
    }

    #
    #   Test chained actions in the root controller
    #
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained::Root->rootsub
          TestApp::Controller::Action::Chained::Root->endpointsub
          TestApp::Controller::Root->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/rootsub/1/endpointsub/2'), 'chained in root namespace' );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, '', 'Content OK' );
    }

    #
    #   Complex path with multiple empty pathparts
    #
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained->mult_nopp_base
          TestApp::Controller::Action::Chained->mult_nopp_all
          TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/chained/mult_nopp'),
            "Complex path with multiple empty pathparts" );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, '; ', 'Content OK' );
    }

    #
    #   Complex path with multiple non-capturing pathparts
    # PathPart('') CaptureArgs(0), PathPart('foo') CaptureArgs(0), PathPart('') Args(0)
    # should win over PathPart('') CaptureArgs(1), PathPart('') Args(0)
    #
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained->mult_nopp2_base
          TestApp::Controller::Action::Chained->mult_nopp2_nocap
          TestApp::Controller::Action::Chained->mult_nopp2_action
          TestApp::Controller::Action::Chained->mult_nopp2_action_default
          TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/chained/mult_nopp2/action'),
            "Complex path with multiple non-capturing pathparts" );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, '; ', 'Content OK' );
    }

    #
    #   Higher Args() hiding more specific CaptureArgs chains sections
    #
    {
        my @expected = qw[
            TestApp::Controller::Action::Chained->begin
            TestApp::Controller::Action::Chained->cc_base
            TestApp::Controller::Action::Chained->cc_link
            TestApp::Controller::Action::Chained->cc_anchor
            TestApp::Controller::Action::Chained->end
            ];

t/aggregate/live_component_controller_action_chained.t  view on Meta::CPAN


        # should dispatch to /base/test_one_arg
        ok( my $response = request('http://localhost/captureargs/test/one'),
            'Correct pathpart/arg ran' );
        TODO: {
        local $TODO = 'Known bug';
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, 'base; test_plus_arg; one;', 'Content OK' );
        }
    }

    #
    #   Args(0) should win over Args() if we actually have no arguments.
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained::ArgsOrder->base
          TestApp::Controller::Action::Chained::ArgsOrder->index
          TestApp::Controller::Action::Chained::ArgsOrder->end
        ];

        my $expected = join( ", ", @expected );

    # With no args, we should run "index"
        ok( my $response = request('http://localhost/argsorder/'),
            'Correct arg order ran' );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, 'base; ; index; ', 'Content OK' );

    # With args given, run "all"
        ok( $response = request('http://localhost/argsorder/X'),
            'Correct arg order ran' );
        is( $response->header('X-Catalyst-Executed'),
        join(", ",
         qw[
             TestApp::Controller::Action::Chained->begin
             TestApp::Controller::Action::Chained::ArgsOrder->base
             TestApp::Controller::Action::Chained::ArgsOrder->all
             TestApp::Controller::Action::Chained::ArgsOrder->end
          ])
      );
        is( $response->content, 'base; ; all; X', 'Content OK' );

    }

    #
    #   PathPrefix
    #
    {
        my @expected = qw[
          TestApp::Controller::Action::Chained->begin
          TestApp::Controller::Action::Chained::PathPrefix->instance
          TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/action/chained/pathprefix/1'),
            "PathPrefix (as an endpoint)" );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
        is( $response->content, '; 1', 'Content OK' );
    }

    #
    #   static paths vs. captures
    #
    {
        my @expected = qw[
            TestApp::Controller::Action::Chained->begin
            TestApp::Controller::Action::Chained->apan
            TestApp::Controller::Action::Chained->korv
            TestApp::Controller::Action::Chained->static_end
            TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/action/chained/static_end'),
            "static paths are prefered over captures" );
        is( $response->header('X-Catalyst-Executed'),
            $expected, 'Executed actions' );
    }

    #
    #   */search
    #   doc/*
    #
    #   request for doc/search should end up in doc/*
    {
        my @expected = qw[
            TestApp::Controller::Action::Chained->begin
            TestApp::Controller::Action::Chained->doc_star
            TestApp::Controller::Action::Chained->end
        ];

        my $expected = join( ", ", @expected );

        ok( my $response = request('http://localhost/chained/doc/search'),
            "we prefer static path parts earlier in the chain" );
        TODO: {
            local $TODO = 'gbjk never got off his ass and fixed this';
            is( $response->header('X-Catalyst-Executed'),
                $expected, 'Executed actions' );
        }
    }

    {
        ok( my $content =
            get('http://localhost/chained/capture%2Farg%3B/return_arg/foo%2Fbar%3B'),
            'request with URI-encoded arg' );
        like( $content, qr{foo/bar;\z}, 'args decoded' );
        like( $content, qr{capture/arg;}, 'captureargs decoded' );
    }
    {
        ok( my $content =
            get('http://localhost/chained/return_arg_decoded/foo%2Fbar%3B'),
            'request with URI-encoded arg' );
        like( $content, qr{foo/bar;\z}, 'args decoded' );



( run in 0.948 second using v1.01-cache-2.11-cpan-39bf76dae61 )