allow passing either psgi app, or application object to Web::Dispatch
[catagits/Web-Simple.git] / t / dispatch_misc.t
CommitLineData
35075f9d 1use strict;
2use warnings FATAL => 'all';
3no warnings::illegalproto;
4
5use Test::More;
6
7use HTTP::Request::Common qw(GET POST);
8use Web::Dispatch;
9use HTTP::Response;
efbff594 10use Web::Dispatch::Predicates 'match_true';
35075f9d 11
12my @dispatch;
13
14{
15 use Web::Simple 'MiscTest';
16
17 package MiscTest;
18 sub dispatch_request { @dispatch }
19}
20
21my $app = MiscTest->new;
22sub run_request { $app->run_test_request( @_ ); }
23
24app_is_non_plack();
e5250d96 25app_is_object();
35075f9d 26plack_app_return();
27broken_route_def();
19b1ef0b 28invalid_psgi_responses();
35075f9d 29middleware_as_only_route();
30route_returns_middleware_plus_extra();
31route_returns_undef();
efbff594 32matcher_nonsub_pair();
35075f9d 33
34done_testing();
35
36sub app_is_non_plack {
37
38 my $r = HTTP::Response->new( 999 );
39
e5250d96 40 my $d = Web::Dispatch->new( dispatch_app => $r );
35075f9d 41 eval { $d->call };
42
43 like $@, qr/No idea how we got here with HTTP::Response/,
44 "Web::Dispatch dies when run with an app() that is a non-PSGI object";
45 undef $@;
46}
47
e5250d96 48sub app_is_object {
49 {
50
51 package ObjectApp;
52 use Moo;
53 sub to_app { [ 999, [], ["ok"] ] }
54 }
55
56 my $d = Web::Dispatch->new( dispatch_object => ObjectApp->new );
57 my $res = $d->call;
58
59 cmp_ok $res->[0], '==', 999, "Web::Dispatch can dispatch properly, given only an object with to_app method";
60}
61
35075f9d 62sub plack_app_return {
63 {
64
65 package FauxPlackApp;
66 sub new { bless {}, $_[0] }
67
68 sub to_app {
69 return sub {
70 [ 999, [], [""] ];
71 };
72 }
73 }
74
75 @dispatch = (
76 sub (/) {
77 FauxPlackApp->new;
78 }
79 );
80
81 my $get = run_request( GET => 'http://localhost/' );
82
83 cmp_ok $get->code, '==', 999,
84 "when a route returns a thing that look like a Plack app, the web app redispatches to that thing";
85}
86
87sub broken_route_def {
88
89 @dispatch = ( '/' => "" );
90
91 my $get = run_request( GET => 'http://localhost/' );
92
93 cmp_ok $get->code, '==', 500, "a route definition by hash that doesn't pair a sub with a route dies";
94 like $get->content, qr[No idea how we got here with /], "the error message points out the broken definition";
95}
96
19b1ef0b 97sub invalid_psgi_responses {
98 undef $@;
35075f9d 99
19b1ef0b 100 my @responses = (
101 [ [ sub { } ], "an arrayref with a single sub in it" ],
102 [ ["moo"], "an arrayref with a scalar that is not a sub" ],
23dee6a3 103 [ bless( {}, "FauxObject" ), "an object without to_app method" ],
35075f9d 104 );
105
19b1ef0b 106 for my $response ( @responses ) {
107 @dispatch = ( sub (/) { $response->[0] } );
35075f9d 108
19b1ef0b 109 eval { run_request( GET => 'http://localhost/' ) };
110
111 like $@, qr/Can't call method "request" on an undefined value .*MockHTTP/,
112 sprintf(
113 "if a route returns %s, then that is returned as a response by WD, causing HTTP::Message::PSGI to choke",
114 $response->[1] );
115 undef $@;
116 }
35075f9d 117}
118
119sub middleware_as_only_route {
120 @dispatch = ( bless {}, "Plack::Middleware" );
121
122 my $get = run_request( GET => 'http://localhost/' );
123
124 cmp_ok $get->code, '==', 500, "a route definition consisting of only a middleware causes a bail";
125 like $get->content, qr[Multiple results but first one is a middleware \(Plack::Middleware=],
126 "the error message mentions the middleware class";
127}
128
129sub route_returns_middleware_plus_extra {
130 @dispatch = (
131 sub (/) {
132 return ( bless( {}, "Plack::Middleware" ), "" );
133 }
134 );
135
136 my $get = run_request( GET => 'http://localhost/' );
137
138 cmp_ok $get->code, '==', 500, "a route returning a middleware and at least one other variable causes a bail";
139 like $get->content,
140 qr[Multiple results but first one is a middleware \(Plack::Middleware=],
141 "the error message mentions the middleware class";
142}
143
144sub route_returns_undef {
145 @dispatch = (
146 sub (/) {
147 (
148 sub(/) {
149 undef;
150 },
151 sub(/) {
152 [ 900, [], [""] ];
153 }
154 );
155 },
156 sub () {
157 [ 400, [], [""] ];
158 }
159 );
160
161 my $get = run_request( GET => 'http://localhost/' );
162
163 cmp_ok $get->code, '==', 900, "a route that returns undef causes WD to ignore it and resume dispatching";
164}
efbff594 165
166sub matcher_nonsub_pair {
167 @dispatch = ( match_true() => 5 );
168
169 my $get = run_request( GET => 'http://localhost/' );
170
171 cmp_ok $get->code, '==', 500, "a route definition that pairs a WD::Matcher a non-sub dies";
172 like $get->content, qr[No idea how we got here with Web::Dispatch::M],
173 "the error message points out the broken definition";
174}