a12e7668a45cb03fbc0eadcaf3b296c8b06b9b85
[catagits/Catalyst-Controller-DBIC-API.git] / t / rpc / create.t
1 use strict;
2 use warnings;
3
4 use lib 't/lib';
5
6 my $base = 'http://localhost';
7 my $content_type = [ 'Content-Type', 'application/x-www-form-urlencoded' ];
8
9 use RestTest;
10 use DBICTest;
11 use Test::More;
12 use Test::WWW::Mechanize::Catalyst 'RestTest';
13 use HTTP::Request::Common;
14 use JSON;
15
16 my $json = JSON->new->utf8;
17
18 my $mech = Test::WWW::Mechanize::Catalyst->new;
19 ok( my $schema = DBICTest->init_schema(), 'got schema' );
20
21 my $artist_create_url     = "$base/api/rpc/artist/create";
22 my $any_artist_create_url = "$base/api/rpc/any/artist/create";
23 my $producer_create_url   = "$base/api/rpc/producer/create";
24
25 # test validation when no params sent
26 {
27     my $req = POST(
28         $artist_create_url,
29         { wrong_param => 'value' },
30         'Accept' => 'text/json'
31     );
32     $mech->request( $req, $content_type );
33     cmp_ok( $mech->status, '==', 400,
34         'attempt without required params caught' );
35     my $response = $json->decode( $mech->content );
36     like(
37         $response->{messages}->[0],
38         qr/No value supplied for name and no default/,
39         'correct message returned'
40     );
41 }
42
43 # test default value used if default value exists
44 {
45     my $req = POST(
46         $producer_create_url,
47         {
48
49         },
50         'Accept' => 'text/json'
51     );
52     $mech->request( $req, $content_type );
53     cmp_ok( $mech->status, '==', 200,
54         'default value used when not supplied' );
55     ok( $schema->resultset('Producer')->find( { name => 'fred' } ),
56         'record created with default name' );
57 }
58
59 # test create works as expected when passing required value
60 {
61     my $req = POST(
62         $producer_create_url,
63         { name => 'king luke' },
64         'Accept' => 'text/json'
65     );
66     $mech->request( $req, $content_type );
67     cmp_ok( $mech->status, '==', 200, 'param value used when supplied' );
68
69     my $new_obj =
70         $schema->resultset('Producer')->find( { name => 'king luke' } );
71     ok( $new_obj, 'record created with specified name' );
72
73     my $response = $json->decode( $mech->content );
74     is_deeply(
75         $response->{list},
76         { $new_obj->get_columns },
77         'json for new producer returned'
78     );
79 }
80
81 # test create of single related row
82 {
83     my $test_data = $json->encode(
84         { name => 'Futuristic Artist', cds => { 'title' => 'snarky cd name', year => '3030' } }
85     );
86     my $req = PUT($artist_create_url);
87     $req->content_type('text/x-json');
88     $req->content_length(
89         do { use bytes; length($test_data) }
90     );
91     $req->content($test_data);
92     $mech->request($req);
93     cmp_ok( $mech->status, '==', 200, 'request with single related row okay' );
94     my $count = $schema->resultset('Artist')
95         ->search({ name => 'Futuristic Artist' })
96         ->count;
97     ok( $count, 'record with related object created' );
98     $count = $schema->resultset('Artist')
99         ->search_related('cds', { title => 'snarky cd name' })
100         ->count;
101     ok( $count, "record's related object created" );
102 }
103
104 # test create of multiple related rows
105 {
106     my $test_data = $json->encode(
107         { name => 'Futuristic Artist 2',
108           cds => [
109             { 'title' => 'snarky cd name 2', year => '3030' },
110             { 'title' => 'snarky cd name 3', year => '3030' },
111           ]
112         }
113     );
114
115     my $req = PUT($artist_create_url);
116     $req->content_type('text/x-json');
117     $req->content_length(
118         do { use bytes; length($test_data) }
119     );
120     $req->content($test_data);
121     $mech->request($req);
122     cmp_ok( $mech->status, '==', 200, 'request with multiple related rows okay' );
123     my $count = $schema->resultset('Artist')
124         ->search({ name => 'Futuristic Artist 2' })
125         ->count;
126     ok( $count, 'record with related object created' );
127     $count = $schema->resultset('Artist')
128         ->search_related('cds', { title => ['snarky cd name 2','snarky cd name 3'] })
129         ->count;
130     ok( $count == 2, "record's related objects created" ) or explain diag $count;
131
132 }
133
134 # test stash config handling
135 {
136     my $req = POST(
137         $any_artist_create_url,
138         { name => 'queen monkey' },
139         'Accept' => 'text/json'
140     );
141     $mech->request( $req, $content_type );
142     cmp_ok( $mech->status, '==', 200, 'stashed config okay' );
143
144     my $new_obj =
145         $schema->resultset('Artist')->find( { name => 'queen monkey' } );
146     ok( $new_obj, 'record created with specified name' );
147
148     my $response = $json->decode( $mech->content );
149     is_deeply(
150         $response,
151         { success => 'true' },
152         'json for new artist returned'
153     );
154 }
155
156 # test create returns an error as expected when passing invalid value
157 {
158     my $data = {
159         producerid => 100,
160         name       => 'Producer',
161     };
162
163     my $req = POST($producer_create_url, $data, 'Accept' => 'text/json');
164     $mech->request( $req, $content_type );
165     cmp_ok( $mech->status, '==', 200, 'create with pk value ok' );
166     my $response = $json->decode( $mech->content );
167     is_deeply(
168         $response,
169         { success => 'true', list => $data },
170         'json for producer with pk value ok'
171     );
172     # try to insert same data again, as this seems to be the only way to
173     # force an insert to fail for SQLite.
174     # It accepts too long columns as well as wrong datatypes without errors.
175     # The bind with datatype of newer DBIC versions numifies non-integer
176     # values passed as pk value too.
177     $mech->request( $req, $content_type );
178     cmp_ok( $mech->status, '==', 400, 'invalid param value produces error' );
179 }
180
181 # test creating record with multiple related-rows
182
183 done_testing();