allow creating multiple related columns when updating or creating new records
[catagits/Catalyst-Controller-DBIC-API.git] / t / rpc / create.t
CommitLineData
d2739840 1use strict;
2use warnings;
3
4use lib 't/lib';
5
6my $base = 'http://localhost';
7my $content_type = [ 'Content-Type', 'application/x-www-form-urlencoded' ];
8
9use RestTest;
10use DBICTest;
11use Test::More;
12use Test::WWW::Mechanize::Catalyst 'RestTest';
13use HTTP::Request::Common;
0b0bf911 14use JSON;
15
16my $json = JSON->new->utf8;
d2739840 17
18my $mech = Test::WWW::Mechanize::Catalyst->new;
0b0bf911 19ok( my $schema = DBICTest->init_schema(), 'got schema' );
d2739840 20
0b0bf911 21my $artist_create_url = "$base/api/rpc/artist/create";
d2739840 22my $any_artist_create_url = "$base/api/rpc/any/artist/create";
0b0bf911 23my $producer_create_url = "$base/api/rpc/producer/create";
d2739840 24
25# test validation when no params sent
26{
0b0bf911 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 );
d2739840 41}
42
43# test default value used if default value exists
44{
0b0bf911 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' );
d2739840 57}
58
59# test create works as expected when passing required value
60{
0b0bf911 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 );
d2739840 79}
80
88b67dcd 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
d2739840 134# test stash config handling
135{
0b0bf911 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 );
d2739840 154}
155
156# test create returns an error as expected when passing invalid value
157{
fd6fb6c9 158 my $data = {
159 producerid => 100,
160 name => 'Producer',
161 };
0b0bf911 162
fd6fb6c9 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'
0b0bf911 171 );
fd6fb6c9 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.
0b0bf911 177 $mech->request( $req, $content_type );
178 cmp_ok( $mech->status, '==', 400, 'invalid param value produces error' );
d2739840 179}
180
88b67dcd 181# test creating record with multiple related-rows
182
d2739840 183done_testing();