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