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