When from_psgi_response, a bug when headers are already output and charset is set...
[catagits/Catalyst-Runtime.git] / t / psgi_utils.t
CommitLineData
9c7b6768 1use warnings;
2use strict;
3
4# Make it easier to mount PSGI apps under catalyst
5
b5436c19 6my $psgi_app = sub {
7 my $req = Plack::Request->new(shift);
8 return [200,[],[$req->path]];
9};
10
9c7b6768 11{
b194746d 12 package MyApp::PSGIObject;
13
14 sub as_psgi {
15 return [200, ['Content-Type' => 'text/plain'], ['as_psgi']];
16 };
17
4477b313 18 package MyApp::Controller::Docs;
09b86ef3 19 $INC{'MyApp/Controller/Docs.pm'} = __FILE__;
9c7b6768 20
21 use base 'Catalyst::Controller';
22 use Plack::Request;
23 use Catalyst::Utils;
24
b194746d 25 sub as_psgi :Local {
26 my ($self, $c) = @_;
27 my $as_psgi = bless +{}, 'MyApp::PSGIObject';
28 $c->res->from_psgi_response($as_psgi);
29 }
30
4477b313 31 sub name :Local {
32 my ($self, $c) = @_;
33 my $env = $c->Catalyst::Utils::env_at_action;
34 $c->res->from_psgi_response(
35 $psgi_app->($env));
36
37 }
38
39 sub name_args :Local Args(1) {
40 my ($self, $c, $arg) = @_;
41 my $env = $c->Catalyst::Utils::env_at_action;
42 $c->res->from_psgi_response(
43 $psgi_app->($env));
44 }
45
67fd25bc 46 sub filehandle :Local {
47 my ($self, $c, $arg) = @_;
48 my $path = File::Spec->catfile('t', 'utf8.txt');
49 open(my $fh, '<', $path) || die "trouble: $!";
50 $c->res->from_psgi_response([200, ['Content-Type'=>'text/html'], $fh]);
51 }
52
53 sub direct :Local {
54 my ($self, $c, $arg) = @_;
55 $c->res->from_psgi_response([200, ['Content-Type'=>'text/html'], ["hello","world"]]);
56 }
57
cc7738c0 58 sub streaming_body :Local {
59 my ($self, $c) = @_;
60 my $psgi_app = sub {
61 my $respond = shift;
62 my $writer = $respond->([200,["Content-Type" => "text/plain"]]);
63 $writer->write("body");
64 $writer->close;
65 };
66 $c->res->from_psgi_response($psgi_app);
67 }
68 sub streaming_body_with_charset :Local {
69 my ($self, $c) = @_;
70 my $psgi_app = sub {
71 my $respond = shift;
72 my $writer = $respond->([200,["Content-Type" => "text/plain; charset=utf-8"]]);
73 $writer->write("body");
74 $writer->close;
75 };
76 $c->res->from_psgi_response($psgi_app);
77 }
78
9c7b6768 79 package MyApp::Controller::User;
09b86ef3 80 $INC{'MyApp/Controller/User.pm'} = __FILE__;
9c7b6768 81
82 use base 'Catalyst::Controller';
83 use Plack::Request;
84 use Catalyst::Utils;
9c7b6768 85
86 sub local_example :Local {
87 my ($self, $c) = @_;
88 my $env = $self->get_env($c);
89 $c->res->from_psgi_response(
90 $psgi_app->($env));
91 }
92
93 sub local_example_args1 :Local Args(1) {
94 my ($self, $c) = @_;
95 my $env = $self->get_env($c);
96 $c->res->from_psgi_response(
97 $psgi_app->($env));
98 }
99
100 sub path_example :Path('path-example') {
101 my ($self, $c) = @_;
102 my $env = $self->get_env($c);
103 $c->res->from_psgi_response(
104 $psgi_app->($env));
105 }
106
107 sub path_example_args1 :Path('path-example-args1') {
108 my ($self, $c) = @_;
109 my $env = $self->get_env($c);
110 $c->res->from_psgi_response(
111 $psgi_app->($env));
112 }
113
114 sub chained :Chained(/) PathPrefix CaptureArgs(0) { }
115
116 sub from_chain :Chained('chained') PathPart('') CaptureArgs(0) {}
117
118 sub end_chain :Chained('from_chain') PathPath(abc-123) Args(1)
119 {
120 my ($self, $c) = @_;
121 my $env = $self->get_env($c);
122 $c->res->from_psgi_response(
123 $psgi_app->($env));
124 }
d12acbe6 125
126 sub mounted :Local Args(1) {
127 my ($self, $c, $arg) = @_;
128 our $app ||= ref($c)->psgi_app;
129 my $env = $self->get_env($c);
130 $c->res->from_psgi_response(
131 $app->($env));
132 }
133
134 sub mount_arg :Path(/mounted) Arg(1) {
135 my ($self, $c, $arg) = @_;
136 my $uri = $c->uri_for( $self->action_for('local_example_args1'),$arg);
137 $c->res->body("$uri");
138 }
139
140 sub mount_noarg :Path(/mounted_no_arg) {
141 my ($self, $c) = @_;
142 my $uri = $c->uri_for( $self->action_for('local_example_args1'),444);
143 $c->res->body("$uri");
144 }
145
88e5a8b0 146
9c7b6768 147 sub get_env {
148 my ($self, $c) = @_;
149 if($c->req->query_parameters->{path_prefix}) {
150 return $c->Catalyst::Utils::env_at_path_prefix;
151 } elsif($c->req->query_parameters->{env_path}) {
152 return $c->Catalyst::Utils::env_at_action;
153 } elsif($c->req->query_parameters->{path}) {
154 return $c->Catalyst::Utils::env_at_request_uri;
155 } else {
156 return $c->req->env;
157 }
158 }
159
9c7b6768 160 package MyApp;
161 use Catalyst;
162 MyApp->setup;
163
164}
165
166use Test::More;
167use Catalyst::Test 'MyApp';
168
d12acbe6 169{
b194746d 170 my ($res, $c) = ctx_request('/docs/as_psgi');
171 is $res->content, 'as_psgi';
172}
173
174{
d12acbe6 175 my ($res, $c) = ctx_request('/user/mounted/111?path_prefix=1');
176 is $c->action, 'user/mounted';
177 is $res->content, 'http://localhost/user/user/local_example_args1/111';
178 is_deeply $c->req->args, [111];
179}
180
181{
182 my ($res, $c) = ctx_request('/user/mounted/mounted_no_arg?env_path=1');
183 is $c->action, 'user/mounted';
184 is $res->content, 'http://localhost/user/mounted/user/local_example_args1/444';
185 is_deeply $c->req->args, ['mounted_no_arg'];
186}
187
9c7b6768 188# BEGIN [user/local_example]
189{
190 my ($res, $c) = ctx_request('/user/local_example');
191 is $c->action, 'user/local_example';
192 is $res->content, '/user/local_example';
193 is_deeply $c->req->args, [];
194}
195
196{
197 my ($res, $c) = ctx_request('/user/local_example/111/222');
198 is $c->action, 'user/local_example';
199 is $res->content, '/user/local_example/111/222';
200 is_deeply $c->req->args, [111,222];
201}
202
203{
204 my ($res, $c) = ctx_request('/user/local_example?path_prefix=1');
205 is $c->action, 'user/local_example';
206 is $res->content, '/local_example';
207 is_deeply $c->req->args, [];
208}
209
210{
211 my ($res, $c) = ctx_request('/user/local_example/111/222?path_prefix=1');
212 is $c->action, 'user/local_example';
213 is $res->content, '/local_example/111/222';
214 is_deeply $c->req->args, [111,222];
215}
216
217{
218 my ($res, $c) = ctx_request('/user/local_example?env_path=1');
219 is $c->action, 'user/local_example';
220 is $res->content, '/';
221 is_deeply $c->req->args, [];
222}
223
224{
225 my ($res, $c) = ctx_request('/user/local_example/111/222?env_path=1');
226 is $c->action, 'user/local_example';
227 is $res->content, '/111/222';
228 is_deeply $c->req->args, [111,222];
229}
230
231{
232 my ($res, $c) = ctx_request('/user/local_example?path=1');
233 is $c->action, 'user/local_example';
234 is $res->content, '/';
235 is_deeply $c->req->args, [];
236}
237
238{
239 my ($res, $c) = ctx_request('/user/local_example/111/222?path=1');
240 is $c->action, 'user/local_example';
241 is $res->content, '/';
242 is_deeply $c->req->args, [111,222];
243}
244
245# END [user/local_example]
246
247# BEGIN [/user/local_example_args1/***/]
248
249{
250 my ($res, $c) = ctx_request('/user/local_example_args1/333');
251 is $c->action, 'user/local_example_args1';
252 is $res->content, '/user/local_example_args1/333';
253 is_deeply $c->req->args, [333];
254}
255
256{
257 my ($res, $c) = ctx_request('/user/local_example_args1/333?path_prefix=1');
258 is $c->action, 'user/local_example_args1';
259 is $res->content, '/local_example_args1/333';
260 is_deeply $c->req->args, [333];
261}
262
263{
264 my ($res, $c) = ctx_request('/user/local_example_args1/333?env_path=1');
265 is $c->action, 'user/local_example_args1';
266 is $res->content, '/333';
267 is_deeply $c->req->args, [333];
268}
269
270{
271 my ($res, $c) = ctx_request('/user/local_example_args1/333?path=1');
272 is $c->action, 'user/local_example_args1';
273 is $res->content, '/';
274 is_deeply $c->req->args, [333];
275}
276
277# END [/user/local_example_args1/***/]
278
88e5a8b0 279# BEGIN [/user/path-example]
9c7b6768 280
281{
282 my ($res, $c) = ctx_request('/user/path-example');
283 is $c->action, 'user/path_example';
284 is $res->content, '/user/path-example';
285 is_deeply $c->req->args, [];
286}
287
288{
289 my ($res, $c) = ctx_request('/user/path-example?path_prefix=1');
290 is $c->action, 'user/path_example';
291 is $res->content, '/path-example';
292 is_deeply $c->req->args, [];
293}
294
295{
296 my ($res, $c) = ctx_request('/user/path-example?env_path=1');
297 is $c->action, 'user/path_example';
298 is $res->content, '/';
299 is_deeply $c->req->args, [];
300}
301
302{
303 my ($res, $c) = ctx_request('/user/path-example?path=1');
304 is $c->action, 'user/path_example';
305 is $res->content, '/';
306 is_deeply $c->req->args, [];
307}
308
309
310{
311 my ($res, $c) = ctx_request('/user/path-example/111/222');
312 is $c->action, 'user/path_example';
313 is $res->content, '/user/path-example/111/222';
314 is_deeply $c->req->args, [111,222];
315}
316
317{
318 my ($res, $c) = ctx_request('/user/path-example/111/222?path_prefix=1');
319 is $c->action, 'user/path_example';
320 is $res->content, '/path-example/111/222';
321 is_deeply $c->req->args, [111,222];
322}
323
324{
325 my ($res, $c) = ctx_request('/user/path-example/111/222?env_path=1');
326 is $c->action, 'user/path_example';
327 is $res->content, '/111/222';
328 is_deeply $c->req->args, [111,222];
329}
330
331{
332 my ($res, $c) = ctx_request('/user/path-example/111/222?path=1');
333 is $c->action, 'user/path_example';
334 is $res->content, '/';
335 is_deeply $c->req->args, [111,222];
336}
337
338{
339 my ($res, $c) = ctx_request('/user/path-example-args1/333');
340 is $c->action, 'user/path_example_args1';
341 is $res->content, '/user/path-example-args1/333';
342 is_deeply $c->req->args, [333];
343}
344
345{
346 my ($res, $c) = ctx_request('/user/path-example-args1/333?path_prefix=1');
347 is $c->action, 'user/path_example_args1';
348 is $res->content, '/path-example-args1/333';
349 is_deeply $c->req->args, [333];
350}
351
352{
353 my ($res, $c) = ctx_request('/user/path-example-args1/333?env_path=1');
354 is $c->action, 'user/path_example_args1';
355 is $res->content, '/333';
356 is_deeply $c->req->args, [333];
357}
358
359{
360 my ($res, $c) = ctx_request('/user/path-example-args1/333?path=1');
361 is $c->action, 'user/path_example_args1';
362 is $res->content, '/';
363 is_deeply $c->req->args, [333];
364}
365
366# Chaining test /user/end_chain/*
367#
368#
369
370{
371 my ($res, $c) = ctx_request('/user/end_chain/444');
372 is $c->action, 'user/end_chain';
373 is $res->content, '/user/end_chain/444';
374 is_deeply $c->req->args, [444];
375}
376
377{
378 my ($res, $c) = ctx_request('/user/end_chain/444?path_prefix=1');
379 is $c->action, 'user/end_chain';
380 is $res->content, '/end_chain/444';
381 is_deeply $c->req->args, [444];
382}
383
384{
385 my ($res, $c) = ctx_request('/user/end_chain/444?env_path=1');
386 is $c->action, 'user/end_chain';
387 is $res->content, '/444';
388 is_deeply $c->req->args, [444];
389}
390
391{
392 my ($res, $c) = ctx_request('/user/end_chain/444?path=1');
393 is $c->action, 'user/end_chain';
394 is $res->content, '/';
395 is_deeply $c->req->args, [444];
396}
397
4477b313 398{
399 my ($res, $c) = ctx_request('/docs/name');
400 is $c->action, 'docs/name';
401 is $res->content, '/';
402 is_deeply $c->req->args, [];
403}
404
405{
406 my ($res, $c) = ctx_request('/docs/name/111/222');
407 is $c->action, 'docs/name';
408 is $res->content, '/111/222';
409 is_deeply $c->req->args, [111,222];
410}
411
412{
413 my ($res, $c) = ctx_request('/docs/name_args/111');
414 is $c->action, 'docs/name_args';
415 is $res->content, '/111';
416 is_deeply $c->req->args, [111];
417}
9c7b6768 418
67fd25bc 419{
420 use utf8;
421 use Encode;
422 my ($res, $c) = ctx_request('/docs/filehandle');
423 is Encode::decode_utf8($res->content), "<p>This is stream_body_fh action ♥</p>\n";
424}
425
426{
427 my ($res, $c) = ctx_request('/docs/direct');
428 is $res->content, "helloworld";
429}
430
cc7738c0 431{
432 my ($res, $c) = ctx_request('/docs/streaming_body');
433 is $res->content, "body";
434}
435{
436 my ($res, $c) = ctx_request('/docs/streaming_body_with_charset');
437 is $res->content, "body";
438}
439
9c7b6768 440done_testing();