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