troubling test results
[catagits/Catalyst-Runtime.git] / t / utf_incoming.t
1 use utf8;
2 use warnings;
3 use strict;
4 use Test::More;
5 use HTTP::Request::Common;
6 use Encode 2.21 'decode_utf8', 'encode_utf8';
7 use File::Spec;
8
9 # Test cases for incoming utf8 
10
11 {
12   package MyApp::Controller::Root;
13   $INC{'MyApp/Controller/Root.pm'} = __FILE__;
14
15   use base 'Catalyst::Controller';
16
17   sub heart :Path('♥') {
18     my ($self, $c) = @_;
19     $c->response->content_type('text/html');
20     $c->response->body("<p>This is path-heart action ♥</p>");
21     # We let the content length middleware find the length...
22   }
23
24   sub hat :Path('^') {
25     my ($self, $c) = @_;
26     $c->response->content_type('text/html');
27     $c->response->body("<p>This is path-hat action ^</p>");
28   }
29
30   sub uri_for :Path('uri_for') {
31     my ($self, $c) = @_;
32     $c->response->content_type('text/html');
33     $c->response->body("${\$c->uri_for($c->controller('Root')->action_for('argend'), ['♥'], '♥', {'♥'=>'♥♥'})}");
34   }
35
36   sub heart_with_arg :Path('a♥') Args(1)  {
37     my ($self, $c, $arg) = @_;
38     $c->response->content_type('text/html');
39     $c->response->body("<p>This is path-heart-arg action $arg</p>");
40     Test::More::is $c->req->args->[0], '♥';
41   }
42
43   sub base :Chained('/') CaptureArgs(0) { }
44     sub link :Chained('base') PathPart('♥') Args(0) {
45       my ($self, $c) = @_;
46       $c->response->content_type('text/html');
47       $c->response->body("<p>This is base-link action ♥</p>");
48     }
49     sub arg :Chained('base') PathPart('♥') Args(1) {
50       my ($self, $c, $arg) = @_;
51       $c->response->content_type('text/html');
52       $c->response->body("<p>This is base-link action ♥ $arg</p>");
53     }
54     sub capture :Chained('base') PathPart('♥') CaptureArgs(1) {
55       my ($self, $c, $arg) = @_;
56       $c->stash(capture=>$arg);
57     }
58       sub argend :Chained('capture') PathPart('♥') Args(1) {
59         my ($self, $c, $arg) = @_;
60         $c->response->content_type('text/html');
61
62         Test::More::is $c->req->args->[0], '♥';
63         Test::More::is $c->req->captures->[0], '♥';
64
65         $c->response->body("<p>This is base-link action ♥ ${\$c->req->args->[0]}</p>");
66
67         # Test to make sure redirect can now take an object (sorry don't have a better place for it
68         # but wanted test coverage.
69         my $location = $c->res->redirect( $c->uri_for($c->controller('Root')->action_for('uri_for')) );
70         Test::More::ok !ref $location; 
71       }
72
73   sub stream_write :Local {
74     my ($self, $c) = @_;
75     $c->response->content_type('text/html');
76     $c->response->write("<p>This is stream_write action ♥</p>");
77   }
78
79   sub stream_write_fh :Local {
80     my ($self, $c) = @_;
81     $c->response->content_type('text/html');
82
83     my $writer = $c->res->write_fh;
84
85     $writer->write(Encode::encode_utf8('<p>This is stream_write_fh action ♥</p>'));
86     $writer->close;
87   }
88
89   sub stream_body_fh :Local {
90     my ($self, $c) = @_;
91
92     my $path = File::Spec->catfile('t', 'utf8.txt');
93     open(my $fh, '<', $path) || die "trouble: $!";
94     $c->response->content_type('text/html');
95     $c->response->body($fh);
96   }
97
98   package MyApp;
99   use Catalyst;
100
101   MyApp->config(encoding=>'UTF-8');
102
103   Test::More::ok(MyApp->setup, 'setup app');
104 }
105
106 ok my $psgi = MyApp->psgi_app, 'build psgi app';
107
108 use Catalyst::Test 'MyApp';
109
110 {
111   my $res = request "/root/♥";
112
113   is $res->code, 200, 'OK';
114   is decode_utf8($res->content), '<p>This is path-heart action ♥</p>', 'correct body';
115   is $res->content_length, 36, 'correct length';
116 }
117
118 {
119   my $res = request "/root/a♥/♥";
120
121   is $res->code, 200, 'OK';
122   is decode_utf8($res->content), '<p>This is path-heart-arg action ♥</p>', 'correct body';
123   is $res->content_length, 40, 'correct length';
124 }
125
126 {
127   my $res = request "/root/^";
128
129   is $res->code, 200, 'OK';
130   is decode_utf8($res->content), '<p>This is path-hat action ^</p>', 'correct body';
131   is $res->content_length, 32, 'correct length';
132 }
133
134 {
135   my $res = request "/base/♥";
136
137   is $res->code, 200, 'OK';
138   is decode_utf8($res->content), '<p>This is base-link action ♥</p>', 'correct body';
139   is $res->content_length, 35, 'correct length';
140 }
141
142 {
143   my ($res, $c) = ctx_request POST "/base/♥?♥=♥&♥=♥♥", [a=>1, b=>'', '♥'=>'♥', '♥'=>'♥♥'];
144
145   is $res->code, 200, 'OK';
146   is decode_utf8($res->content), '<p>This is base-link action ♥</p>', 'correct body';
147   is $res->content_length, 35, 'correct length';
148   is $c->req->parameters->{'♥'}[0], '♥';
149   is $c->req->query_parameters->{'♥'}[0], '♥';
150   is $c->req->body_parameters->{'♥'}[0], '♥';
151   is $c->req->parameters->{'♥'}[0], '♥';
152   is $c->req->parameters->{a}, 1;
153   is $c->req->body_parameters->{a}, 1;
154 }
155
156 {
157   my ($res, $c) = ctx_request GET "/base/♥?♥♥♥";
158
159   is $res->code, 200, 'OK';
160   is decode_utf8($res->content), '<p>This is base-link action ♥</p>', 'correct body';
161   is $res->content_length, 35, 'correct length';
162   is $c->req->query_keywords, '♥♥♥';
163 }
164
165 {
166   my $res = request "/base/♥/♥";
167
168   is $res->code, 200, 'OK';
169   is decode_utf8($res->content), '<p>This is base-link action ♥ ♥</p>', 'correct body';
170   is $res->content_length, 39, 'correct length';
171 }
172
173 {
174   my $res = request "/base/♥/♥/♥/♥";
175
176   is decode_utf8($res->content), '<p>This is base-link action ♥ ♥</p>', 'correct body';
177   is $res->content_length, 39, 'correct length';
178 }
179
180 {
181   my ($res, $c) = ctx_request POST "/base/♥/♥/♥/♥?♥=♥♥", [a=>1, b=>'2', '♥'=>'♥♥'];
182
183   ## Make sure that the urls we generate work the same
184   my $uri_for = $c->uri_for($c->controller('Root')->action_for('argend'), ['♥'], '♥', {'♥'=>'♥♥'});
185   my $uri = $c->req->uri;
186
187   is "$uri", "$uri_for";
188
189   {
190     my ($res, $c) = ctx_request POST "$uri_for", [a=>1, b=>'2', '♥'=>'♥♥'];
191     is $c->req->query_parameters->{'♥'}, '♥♥';
192     is $c->req->body_parameters->{'♥'}, '♥♥';
193     is $c->req->parameters->{'♥'}[0], '♥♥'; #combined with query and body
194   }
195 }
196
197 {
198   my ($res, $c) = ctx_request "/root/uri_for";
199   my $url = $c->uri_for($c->controller('Root')->action_for('argend'), ['♥'], '♥', {'♥'=>'♥♥'});
200
201   is $res->code, 200, 'OK';
202   is decode_utf8($res->content), "$url", 'correct body'; #should do nothing
203   is $res->content, "$url", 'correct body';
204   is $res->content_length, 90, 'correct length';
205 }
206
207 {
208   my $res = request "/root/stream_write";
209
210   is $res->code, 200, 'OK';
211   is decode_utf8($res->content), '<p>This is stream_write action ♥</p>', 'correct body';
212 }
213
214 {
215   my $res = request "/root/stream_body_fh";
216
217   is $res->code, 200, 'OK';
218   is decode_utf8($res->content), "<p>This is stream_body_fh action ♥</p>\n", 'correct body';
219   # Not sure why there is a trailing newline above... its not in catalyst code I can see. Not sure
220   # if is a problem or just an artifact of the why the test stuff works - JNAP
221 }
222
223 {
224    my $res = request "/root/stream_write_fh";
225
226   is $res->code, 200, 'OK';
227   is decode_utf8($res->content), '<p>This is stream_write_fh action ♥</p>', 'correct body';
228 }
229
230
231 done_testing;