fix Test::More version used, for done_testing
[catagits/Web-Simple.git] / t / dispatch_misc.t
CommitLineData
35075f9d 1use strict;
2use warnings FATAL => 'all';
3no warnings::illegalproto;
4
a30328b3 5use Test::More 0.88;
35075f9d 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 }
b2e37c62 19 sub string_method { [ 999, [], [""] ]; }
50e4587f 20
21 sub can {
22 die "Passed undef to can, this blows up on 5.8" unless defined($_[1]);
23 shift->SUPER::can(@_)
24 }
35075f9d 25}
26
27my $app = MiscTest->new;
28sub run_request { $app->run_test_request( @_ ); }
29
b2e37c62 30string_method_name();
35075f9d 31app_is_non_plack();
e5250d96 32app_is_object();
1f8cad5e 33app_is_just_sub();
35075f9d 34plack_app_return();
35broken_route_def();
19b1ef0b 36invalid_psgi_responses();
35075f9d 37middleware_as_only_route();
38route_returns_middleware_plus_extra();
39route_returns_undef();
efbff594 40matcher_nonsub_pair();
50e4587f 41matcher_undef_method();
35075f9d 42
43done_testing();
44
b2e37c62 45sub string_method_name {
46 @dispatch = ( '/' => "string_method" );
47
48 my $get = run_request( GET => 'http://localhost/' );
49
50 cmp_ok $get->code, '==', 999, "a dispatcher that's a string matching a method on the dispatch object gets executed";
51}
52
35075f9d 53sub app_is_non_plack {
54
55 my $r = HTTP::Response->new( 999 );
56
e5250d96 57 my $d = Web::Dispatch->new( dispatch_app => $r );
35075f9d 58 eval { $d->call };
59
60 like $@, qr/No idea how we got here with HTTP::Response/,
61 "Web::Dispatch dies when run with an app() that is a non-PSGI object";
62 undef $@;
63}
64
e5250d96 65sub app_is_object {
66 {
67
68 package ObjectApp;
69 use Moo;
70 sub to_app { [ 999, [], ["ok"] ] }
71 }
72
1f727762 73 my $o = ObjectApp->new;
74 my $d = Web::Dispatch->new( dispatch_object => $o );
e5250d96 75 my $res = $d->call;
76
77 cmp_ok $res->[0], '==', 999, "Web::Dispatch can dispatch properly, given only an object with to_app method";
78}
79
1f8cad5e 80sub app_is_just_sub {
81 my $d = Web::Dispatch->new( dispatch_app => sub () { [ 999, [], ["ok"] ] } );
82 my $res = $d->call( {} );
83
84 cmp_ok $res->[0], '==', 999,
85 "Web::Dispatch can dispatch properly, given only an app that's just a sub, with no object involved";
86}
87
35075f9d 88sub plack_app_return {
89 {
90
91 package FauxPlackApp;
92 sub new { bless {}, $_[0] }
93
94 sub to_app {
95 return sub {
96 [ 999, [], [""] ];
97 };
98 }
99 }
100
101 @dispatch = (
102 sub (/) {
103 FauxPlackApp->new;
104 }
105 );
106
107 my $get = run_request( GET => 'http://localhost/' );
108
109 cmp_ok $get->code, '==', 999,
110 "when a route returns a thing that look like a Plack app, the web app redispatches to that thing";
111}
112
113sub broken_route_def {
114
115 @dispatch = ( '/' => "" );
116
117 my $get = run_request( GET => 'http://localhost/' );
118
119 cmp_ok $get->code, '==', 500, "a route definition by hash that doesn't pair a sub with a route dies";
120 like $get->content, qr[No idea how we got here with /], "the error message points out the broken definition";
121}
122
19b1ef0b 123sub invalid_psgi_responses {
124 undef $@;
35075f9d 125
19b1ef0b 126 my @responses = (
127 [ [ sub { } ], "an arrayref with a single sub in it" ],
128 [ ["moo"], "an arrayref with a scalar that is not a sub" ],
23dee6a3 129 [ bless( {}, "FauxObject" ), "an object without to_app method" ],
35075f9d 130 );
131
19b1ef0b 132 for my $response ( @responses ) {
133 @dispatch = ( sub (/) { $response->[0] } );
35075f9d 134
e0f92e3e 135 my $message = sprintf(
19b1ef0b 136 "if a route returns %s, then that is returned as a response by WD, causing HTTP::Message::PSGI to choke",
e0f92e3e 137 $response->[1]
138 );
139
140 # Somewhere between 1.0028 and 1.0031 Plack changed so that the
141 # FauxObject case became a 500 rather than a die; in case it later does
142 # the same thing for other stuff, just accept either sort of error
143
144 my $res = eval { run_request( GET => 'http://localhost/' ) };
145
146 if ($res) {
147 ok $res->is_error, $message;
148 } else {
149 like $@, qr/Can't call method "request" on an undefined value .*MockHTTP/, $message;
150 }
19b1ef0b 151 undef $@;
152 }
35075f9d 153}
154
155sub middleware_as_only_route {
156 @dispatch = ( bless {}, "Plack::Middleware" );
157
158 my $get = run_request( GET => 'http://localhost/' );
159
160 cmp_ok $get->code, '==', 500, "a route definition consisting of only a middleware causes a bail";
161 like $get->content, qr[Multiple results but first one is a middleware \(Plack::Middleware=],
162 "the error message mentions the middleware class";
163}
164
165sub route_returns_middleware_plus_extra {
166 @dispatch = (
167 sub (/) {
168 return ( bless( {}, "Plack::Middleware" ), "" );
169 }
170 );
171
172 my $get = run_request( GET => 'http://localhost/' );
173
174 cmp_ok $get->code, '==', 500, "a route returning a middleware and at least one other variable causes a bail";
175 like $get->content,
176 qr[Multiple results but first one is a middleware \(Plack::Middleware=],
177 "the error message mentions the middleware class";
178}
179
180sub route_returns_undef {
181 @dispatch = (
182 sub (/) {
183 (
184 sub(/) {
185 undef;
186 },
187 sub(/) {
188 [ 900, [], [""] ];
189 }
190 );
191 },
192 sub () {
193 [ 400, [], [""] ];
194 }
195 );
196
197 my $get = run_request( GET => 'http://localhost/' );
198
199 cmp_ok $get->code, '==', 900, "a route that returns undef causes WD to ignore it and resume dispatching";
200}
efbff594 201
202sub matcher_nonsub_pair {
203 @dispatch = ( match_true() => 5 );
204
205 my $get = run_request( GET => 'http://localhost/' );
206
207 cmp_ok $get->code, '==', 500, "a route definition that pairs a WD::Matcher a non-sub dies";
208 like $get->content, qr[No idea how we got here with Web::Dispatch::M],
209 "the error message points out the broken definition";
210}
50e4587f 211
212sub matcher_undef_method {
213 @dispatch = ( 'GET', undef );
214
215 my $get = run_request( GET => 'http://localhost/' );
216
217 cmp_ok $get->code, '==', 500, "a route definition that pairs a WD::Matcher a non-sub dies";
218 like $get->content, qr[No idea how we got here with GET],
219 "the error message points out the broken definition";
220}