Actually test both the request trait and class
[catagits/Catalyst-Action-REST.git] / t / catalyst-traitfor-request-rest.t
1 use strict;
2 use warnings;
3 use Test::More;
4 use FindBin;
5 use lib ( "$FindBin::Bin/../lib", "$FindBin::Bin/../t/lib" );
6
7 use Catalyst::Request::REST;
8 use Catalyst::TraitFor::Request::REST;
9 use Moose::Meta::Class;
10 use HTTP::Headers;
11 use Catalyst::Log;
12
13 my $anon_class = Moose::Meta::Class->create_anon_class(
14     superclasses => ['Catalyst::Request'],
15     roles        => ['Catalyst::TraitFor::Request::REST'],
16     cache        => 1,
17 )->name;
18
19 # We run the tests twice to make sure Catalyst::Request::REST is
20 # 100% back-compatible.
21 for my $class ( $anon_class, 'Catalyst::Request::REST' ) {
22     {
23         my $request = $class->new(
24             _log => Catalyst::Log->new
25         );
26         $request->{_context} = 'MockContext';
27         $request->headers( HTTP::Headers->new );
28         $request->parameters( {} );
29         $request->method('GET');
30         $request->content_type('text/foobar');
31
32         is_deeply( $request->accepted_content_types, [ 'text/foobar' ],
33                    'content-type set in request headers is found' );
34         is( $request->preferred_content_type, 'text/foobar',
35             'preferred content type is text/foobar' );
36         ok( ! $request->accept_only, 'accept_only is false' );
37         ok( $request->accepts('text/foobar'), 'accepts text/foobar' );
38         ok( ! $request->accepts('text/html'), 'does not accept text/html' );
39     }
40
41     {
42         my $request = $class->new( _log => Catalyst::Log->new );
43         $request->{_context} = 'MockContext';
44         $request->headers( HTTP::Headers->new );
45         $request->parameters( { 'content-type' => 'text/fudge' } );
46         $request->method('GET');
47         $request->content_type('text/foobar');
48
49         is_deeply( $request->accepted_content_types, [ 'text/foobar', 'text/fudge' ],
50                    'content-type set in request headers and type in parameters is found' );
51         is( $request->preferred_content_type, 'text/foobar',
52             'preferred content type is text/foobar' );
53         ok( ! $request->accept_only, 'accept_only is false' );
54         ok( $request->accepts('text/foobar'), 'accepts text/foobar' );
55         ok( $request->accepts('text/fudge'), 'accepts text/fudge' );
56         ok( ! $request->accepts('text/html'), 'does not accept text/html' );
57     }
58
59     {
60         my $request = $class->new( _log => Catalyst::Log->new );
61         $request->{_context} = 'MockContext';
62         $request->headers( HTTP::Headers->new );
63         $request->parameters( { 'content-type' => 'text/fudge' } );
64         $request->method('POST');
65         $request->content_type('text/foobar');
66
67         ok( ! $request->accepts('text/fudge'), 'content type in parameters is ignored for POST' );
68     }
69
70     {
71         my $request = $class->new( _log => Catalyst::Log->new );
72         $request->{_context} = 'MockContext';
73         $request->headers( HTTP::Headers->new );
74         $request->parameters( {} );
75         $request->method('GET');
76         $request->headers->header(
77             'Accept' =>
78             # From Firefox 2.0 when it requests an html page
79             'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
80         );
81
82         is_deeply( $request->accepted_content_types,
83                    [ qw( text/xml application/xml application/xhtml+xml
84                          image/png
85                          text/html
86                          text/plain
87                          */*
88                        ) ],
89                    'accept header is parsed properly' );
90         is( $request->preferred_content_type, 'text/xml',
91             'preferred content type is text/xml' );
92         ok( $request->accept_only, 'accept_only is true' );
93         ok( $request->accepts('text/html'), 'accepts text/html' );
94         ok( $request->accepts('image/png'), 'accepts image/png' );
95         ok( ! $request->accepts('image/svg'), 'does not accept image/svg' );
96     }
97
98     {
99         my $request = $class->new( _log => Catalyst::Log->new );
100         $request->{_context} = 'MockContext';
101         $request->headers( HTTP::Headers->new );
102         $request->parameters( {} );
103         $request->method('GET');
104         $request->content_type('application/json');
105         $request->headers->header(
106             'Accept' =>
107             # From Firefox 2.0 when it requests an html page
108             'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
109         );
110
111         is_deeply( $request->accepted_content_types,
112                    [ qw( application/json
113                          text/xml application/xml application/xhtml+xml
114                          image/png
115                          text/html
116                          text/plain
117                          */*
118                        ) ],
119                    'accept header is parsed properly, and content-type header has precedence over accept' );
120         ok( ! $request->accept_only, 'accept_only is false' );
121     }
122
123     {
124         my $request = $class->new( _log => Catalyst::Log->new );
125         $request->{_context} = 'MockContext';
126         $request->headers( HTTP::Headers->new );
127         $request->parameters( {} );
128         $request->method('GET');
129         $request->content_type('application/json');
130         $request->headers->header(
131             'Accept' =>
132             # From Firefox 2.0 when it requests an html page
133             'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
134         );
135
136         is_deeply( $request->accepted_content_types,
137                    [ qw( application/json
138                          text/xml application/xml application/xhtml+xml
139                          image/png
140                          text/html
141                          text/plain
142                          */*
143                        ) ],
144                    'accept header is parsed properly, and content-type header has precedence over accept' );
145         ok( ! $request->accept_only, 'accept_only is false' );
146     }
147
148     {
149         my $request = $class->new( _log => Catalyst::Log->new );
150         $request->{_context} = 'MockContext';
151         $request->headers( HTTP::Headers->new );
152         $request->parameters( {} );
153         $request->method('GET');
154         $request->content_type('text/x-json');
155         $request->headers->header(
156             'Accept' => 'text/plain,text/x-json',
157         );
158
159         is_deeply( $request->accepted_content_types,
160                    [ qw( text/x-json
161                          text/plain
162                        ) ],
163                    'each type appears only once' );
164     }
165
166     {
167         my $request = $class->new( _log => Catalyst::Log->new );
168         $request->{_context} = 'MockContext';
169         $request->headers( HTTP::Headers->new );
170         $request->parameters( {} );
171         $request->method('GET');
172         $request->content_type('application/json');
173         $request->headers->header(
174             'Accept' => 'text/plain,application/json',
175         );
176
177         is_deeply( $request->accepted_content_types,
178                    [ qw( application/json
179                          text/plain
180                        ) ],
181                    'each type appears only once' );
182     }
183 }
184
185 {
186   local %ENV=%ENV;
187   $ENV{CATALYST_DEBUG} = 0;
188   my $test = 'Test::Catalyst::Action::REST';
189   use_ok $test;
190   ok($test->request_class->does('Catalyst::TraitFor::Request::REST'),
191     'Request does Catalyst::TraitFor::Request::REST');
192
193   my $meta = Moose::Meta::Class->create_anon_class(
194       superclasses => ['Catalyst::Request'],
195   );
196   $meta->add_method('__random_method' => sub { 42 });
197
198   $test->request_class($meta->name);
199   # FIXME - setup_finished(0) is evil!
200   eval { $test->setup_finished(0); $test->setup };
201   ok !$@, 'Can setup again';
202   isnt $test->request_class, $meta->name, 'Different request class';
203   ok $test->request_class->can('__random_method'), 'Is right class';
204   ok $test->request_class->can('data'), 'Also smells like REST subclass';
205
206   {
207     package My::Request;
208     use base 'Catalyst::Request::REST';
209   }
210   $test->request_class('My::Request');
211   eval { $test->setup_finished(0); $test->setup };
212   is $@, '', 'no error from Request::REST subclass';
213 }
214
215 done_testing;
216
217 package MockContext;
218
219 sub prepare_body { }