use JSON instead of JSON::Any to get rid of the CPAN Testers failures when only JSON...
[catagits/Catalyst-Controller-DBIC-API.git] / t / rpc / list.t
1 use 5.6.0;
2
3 use strict;
4 use warnings;
5
6 use lib 't/lib';
7
8 my $base = 'http://localhost';
9
10 use RestTest;
11 use DBICTest;
12 use URI;
13 use Test::More;
14 use Test::WWW::Mechanize::Catalyst 'RestTest';
15 use HTTP::Request::Common;
16 use JSON;
17
18 my $json = JSON->new->utf8;
19
20 my $mech = Test::WWW::Mechanize::Catalyst->new;
21 ok( my $schema = DBICTest->init_schema(), 'got schema' );
22
23 my $artist_list_url   = "$base/api/rpc/artist/list";
24 my $producer_list_url = "$base/api/rpc/producer/list";
25 my $track_list_url    = "$base/api/rpc/track/list";
26 my $cd_list_url       = "$base/api/rpc/cd/list";
27
28 # test open request
29 {
30     my $req = GET(
31         $artist_list_url,
32         {
33
34         },
35         'Accept' => 'text/x-json'
36     );
37     $mech->request($req);
38     cmp_ok( $mech->status, '==', 200, 'open attempt okay' );
39
40     my @expected_response = map {
41         { $_->get_columns }
42     } $schema->resultset('Artist')->all;
43     my $response = $json->decode( $mech->content );
44     is_deeply(
45         $response,
46         { list => \@expected_response, success => 'true' },
47         'correct message returned'
48     );
49 }
50
51 {
52     my $uri = URI->new($artist_list_url);
53     $uri->query_form( { 'search.artistid' => 1 } );
54     my $req = GET( $uri, 'Accept' => 'text/x-json' );
55     $mech->request($req);
56     cmp_ok( $mech->status, '==', 200, 'attempt with basic search okay' );
57
58     my @expected_response = map {
59         { $_->get_columns }
60     } $schema->resultset('Artist')->search( { artistid => 1 } )->all;
61     my $response = $json->decode( $mech->content );
62     is_deeply(
63         $response,
64         { list => \@expected_response, success => 'true' },
65         'correct data returned'
66     );
67 }
68
69 {
70     my $uri = URI->new($artist_list_url);
71     $uri->query_form( { 'search.name.LIKE' => '%waul%' } );
72     my $req = GET( $uri, 'Accept' => 'text/x-json' );
73     $mech->request($req);
74     cmp_ok( $mech->status, '==', 200, 'attempt with basic search okay' );
75
76     my @expected_response = map {
77         { $_->get_columns }
78         } $schema->resultset('Artist')
79         ->search( { name => { LIKE => '%waul%' } } )->all;
80     my $response = $json->decode( $mech->content );
81     is_deeply(
82         $response,
83         { list => \@expected_response, success => 'true' },
84         'correct data returned for complex query'
85     );
86 }
87
88 {
89     my $uri = URI->new($artist_list_url);
90     $uri->query_form(
91         {   'search.name.LIKE'     => '%waul%',
92             'list_returns.0.count' => '*',
93             'as.0'                 => 'count'
94         }
95     );
96     my $req = GET( $uri, 'Accept' => 'text/x-json' );
97     $mech->request($req);
98     cmp_ok( $mech->status, '==', 200, 'attempt with basic count' );
99
100     my @expected_response = map {
101         { $_->get_columns }
102         } $schema->resultset('Artist')
103         ->search( { name => { LIKE => '%waul%' } },
104         { select => [ { count => '*' } ], as => ['count'] } )->all;
105     my $response = $json->decode( $mech->content );
106     is_deeply(
107         $response,
108         { list => \@expected_response, success => 'true' },
109         'correct data returned for count'
110     );
111 }
112
113 {
114     my $uri = URI->new($producer_list_url);
115     my $req = GET( $uri, 'Accept' => 'text/x-json' );
116     $mech->request($req);
117     cmp_ok( $mech->status, '==', 200, 'open producer request okay' );
118
119     my @expected_response = map {
120         { $_->get_columns }
121         } $schema->resultset('Producer')->search( {}, { select => ['name'] } )
122         ->all;
123     my $response = $json->decode( $mech->content );
124     is_deeply(
125         $response,
126         { list => \@expected_response, success => 'true' },
127         'correct data returned for class with list_returns specified'
128     );
129 }
130
131 {
132     my $uri = URI->new($artist_list_url);
133     $uri->query_form( { 'search.cds.title' => 'Forkful of bees' } );
134     my $req = GET( $uri, 'Accept' => 'text/x-json' );
135     $mech->request($req);
136     cmp_ok( $mech->status, '==', 200, 'search related request okay' );
137
138     my @expected_response = map {
139         { $_->get_columns }
140         } $schema->resultset('Artist')
141         ->search( { 'cds.title' => 'Forkful of bees' }, { join => 'cds' } )
142         ->all;
143     my $response = $json->decode( $mech->content );
144     is_deeply(
145         $response,
146         { list => \@expected_response, success => 'true' },
147         'correct data returned for class with list_returns specified'
148     );
149 }
150
151 {
152     my $uri = URI->new($track_list_url);
153     $uri->query_form( { 'list_ordered_by' => 'position' } );
154     my $req = GET( $uri, 'Accept' => 'text/x-json' );
155     $mech->request($req);
156     cmp_ok( $mech->status, '==', 200, 'search related request okay' );
157
158     my @expected_response = map {
159         { $_->get_columns }
160         } $schema->resultset('Track')->search(
161         {},
162         {   group_by => 'position',
163             order_by => 'position ASC',
164             select   => 'position'
165         }
166         )->all;
167     my $response = $json->decode( $mech->content );
168     is_deeply(
169         $response,
170         { list => \@expected_response, success => 'true' },
171         'correct data returned for class with everything specified in class'
172     );
173 }
174
175 {
176     my $uri = URI->new($track_list_url);
177     $uri->query_form(
178         {   'list_ordered_by' => 'cd',
179             'list_returns'    => 'cd',
180             'list_grouped_by' => 'cd'
181         }
182     );
183     my $req = GET( $uri, 'Accept' => 'text/x-json' );
184     $mech->request($req);
185     cmp_ok( $mech->status, '==', 200, 'search related request okay' );
186
187     my @expected_response = map {
188         { $_->get_columns }
189         } $schema->resultset('Track')
190         ->search( {},
191         { group_by => 'cd', order_by => 'cd ASC', select => 'cd' } )->all;
192     my $response = $json->decode( $mech->content );
193     is_deeply(
194         $response,
195         { list => \@expected_response, success => 'true' },
196         'correct data returned when everything overridden in query'
197     );
198 }
199
200 {
201     my $uri = URI->new($track_list_url);
202     $uri->query_form( { 'list_ordered_by' => 'cd', 'list_count' => 2 } );
203     my $req = GET( $uri, 'Accept' => 'text/x-json' );
204     $mech->request($req);
205     cmp_ok( $mech->status, '==', 200, 'list count request okay' );
206
207     my @expected_response = map {
208         { $_->get_columns }
209         } $schema->resultset('Track')->search(
210         {},
211         {   group_by => 'position',
212             order_by => 'position ASC',
213             select   => 'position',
214             rows     => 2
215         }
216         )->all;
217     my $response = $json->decode( $mech->content );
218     is_deeply(
219         $response,
220         { list => \@expected_response, success => 'true' },
221         'correct data returned'
222     );
223 }
224
225 {
226     my $uri = URI->new($track_list_url);
227     $uri->query_form(
228         {   'list_ordered_by' => 'cd',
229             'list_count'      => 2,
230             'list_page'       => 'fgdg'
231         }
232     );
233     my $req = GET( $uri, 'Accept' => 'text/x-json' );
234     $mech->request($req);
235     cmp_ok( $mech->status, '==', 400,
236         'non numeric list_page request not okay' );
237     my $response = $json->decode( $mech->content );
238     is( $response->{success}, 'false', 'correct data returned' );
239     like(
240         $response->{messages}->[0],
241         qr/Attribute \(page\) does not pass the type constraint because: Validation failed for 'Int' (failed )?with value fgdg/,
242         'correct data returned'
243     );
244 }
245
246 {
247     my $uri = URI->new($track_list_url);
248     $uri->query_form(
249         {   'list_ordered_by' => 'cd',
250             'list_count'      => 'sdsdf',
251             'list_page'       => 2
252         }
253     );
254     my $req = GET( $uri, 'Accept' => 'text/x-json' );
255     $mech->request($req);
256     cmp_ok( $mech->status, '==', 400,
257         'non numeric list_count request not okay' );
258     my $response = $json->decode( $mech->content );
259     is( $response->{success}, 'false', 'correct data returned' );
260     like(
261         $response->{messages}->[0],
262         qr/Attribute \(count\) does not pass the type constraint because: Validation failed for 'Int' (failed )?with value sdsdf/,
263         'correct data returned'
264     );
265
266 }
267
268 {
269     my $uri = URI->new($track_list_url);
270     $uri->query_form(
271         { 'list_ordered_by' => 'cd', 'list_count' => 2, 'list_page' => 2 } );
272     my $req = GET( $uri, 'Accept' => 'text/x-json' );
273     $mech->request($req);
274     cmp_ok( $mech->status, '==', 200, 'list count with page request okay' );
275
276     my @expected_response = map {
277         { $_->get_columns }
278         } $schema->resultset('Track')->search(
279         {},
280         {   group_by => 'position',
281             order_by => 'position ASC',
282             select   => 'position',
283             rows     => 2,
284             page     => 2
285         }
286         )->all;
287     my $response = $json->decode( $mech->content );
288     is_deeply(
289         $response,
290         { list => \@expected_response, success => 'true', totalcount => 3 },
291         'correct data returned'
292     );
293 }
294
295 {
296     my $uri = URI->new($track_list_url);
297     $uri->query_form( { 'list_ordered_by' => 'cd', 'list_page' => 2 } );
298     my $req = GET( $uri, 'Accept' => 'text/x-json' );
299     $mech->request($req);
300     cmp_ok( $mech->status, '==', 400,
301         'list page without count returns error' );
302     my $response = $json->decode( $mech->content );
303     like(
304         $response->{messages}->[0],
305         qr/a database error has occured/,
306         'correct data returned'
307     );
308 }
309
310 {
311     my $uri = URI->new($cd_list_url);
312     $uri->query_form( { 'search.artist.name' => 'Caterwauler McCrae' } );
313     my $req = GET( $uri, 'Accept' => 'text/x-json' );
314     $mech->request($req);
315     if (cmp_ok(
316             $mech->status, '==', 200,
317             'search on rel with same name column request okay'
318         )
319         )
320     {
321         my @expected_response = map {
322             { $_->get_columns }
323         } $schema->resultset('CD')->search( { 'me.artist' => 1 } )->all;
324         my $response = $json->decode( $mech->content );
325         is_deeply(
326             $response,
327             { list => \@expected_response, success => 'true' },
328             'correct data returned for search on rel with same name column'
329         );
330     }
331 }
332
333 {
334     my $uri = URI->new($cd_list_url);
335     $uri->query_form( { 'search.artist' => 1 } );
336     my $req = GET( $uri, 'Accept' => 'text/x-json' );
337     $mech->request($req);
338     cmp_ok( $mech->status, '==', 200,
339         'search on column with same name rel request okay' );
340
341     my @expected_response = map {
342         { $_->get_columns }
343     } $schema->resultset('CD')->search( { 'me.artist' => 1 } )->all;
344     my $response = $json->decode( $mech->content );
345     is_deeply(
346         $response,
347         { list => \@expected_response, success => 'true' },
348         'correct data returned for search on column with same name rel'
349     );
350 }
351
352 {
353     my $uri = URI->new($cd_list_url);
354     $uri->query_form(
355         {   'search.title'           => 'Spoonful of bees',
356             'search.tracks.position' => 1
357         }
358     );
359     my $req = GET( $uri, 'Accept' => 'text/x-json' );
360     $mech->request($req);
361     if (cmp_ok(
362             $mech->status, '==', 200,
363             'search on col which exists for me and related table okay'
364         )
365         )
366     {
367         my @expected_response = map {
368             { $_->get_columns }
369             } $schema->resultset('CD')
370             ->search(
371             { 'me.title' => 'Spoonful of bees', 'tracks.position' => 1 },
372             { join       => 'tracks' } )->all;
373         my $response = $json->decode( $mech->content );
374         is_deeply(
375             $response,
376             { list => \@expected_response, success => 'true' },
377             'correct data returned for search on col which exists for me and related table'
378         );
379     }
380 }
381
382 {
383     my $uri = URI->new($cd_list_url);
384     $uri->query_form( { 'list_ordered_by' => 'invalid_column' } );
385     my $req = GET( $uri, 'Accept' => 'text/x-json' );
386     $mech->request($req);
387     if (cmp_ok(
388             $mech->status, '==', 400,
389             'order_by on non-existing col returns error'
390         )
391         )
392     {
393         my $response = $json->decode( $mech->content );
394         is_deeply(
395             $response,
396             {   messages => ['a database error has occured.'],
397                 success  => 'false'
398             },
399             'error returned for order_by on non-existing col'
400         );
401     }
402 }
403
404 {
405     my $uri = URI->new($cd_list_url);
406     $uri->query_form(
407         {   'list_ordered_by' => 'invalid_column',
408             'list_count'      => 2,
409             'list_page'       => 1
410         }
411     );
412     my $req = GET( $uri, 'Accept' => 'text/x-json' );
413     $mech->request($req);
414     if (cmp_ok(
415             $mech->status, '==', 400,
416             'order_by on invalid col with paging returns error'
417         )
418         )
419     {
420         my $response = $json->decode( $mech->content );
421         is_deeply(
422             $response,
423             {   messages => ['a database error has occured.'],
424                 success  => 'false'
425             },
426             'error returned for order_by on non-existing col with paging'
427         );
428     }
429 }
430
431 done_testing();