Commit | Line | Data |
d2739840 |
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; |
0b0bf911 |
14 | use JSON; |
15 | |
16 | my $json = JSON->new->utf8; |
d2739840 |
17 | |
18 | my $mech = Test::WWW::Mechanize::Catalyst->new; |
0b0bf911 |
19 | ok( my $schema = DBICTest->init_schema(), 'got schema' ); |
d2739840 |
20 | |
0b0bf911 |
21 | my $track = $schema->resultset('Track')->first; |
d2739840 |
22 | my %original_cols = $track->get_columns; |
23 | |
24 | my $track_update_url = "$base/api/rpc/track/id/" . $track->id . "/update"; |
0b0bf911 |
25 | my $any_track_update_url = |
26 | "$base/api/rpc/any/track/id/" . $track->id . "/update"; |
0b8c7370 |
27 | my $tracks_update_url = "$base/api/rpc/track/update"; |
d2739840 |
28 | |
88b67dcd |
29 | my $artist_update_url = "$base/api/rpc/artist/id/1/update"; |
30 | |
d2739840 |
31 | # test invalid track id caught |
32 | { |
23bb3784 |
33 | diag 'DBIx::Class warns about a non-numeric id which is ok because we test for that too'; |
0b0bf911 |
34 | foreach my $wrong_id ( 'sdsdsdsd', 3434234 ) { |
35 | my $incorrect_url = "$base/api/rpc/track/id/" . $wrong_id . "/update"; |
36 | my $req = POST( $incorrect_url, { title => 'value' } ); |
37 | |
38 | $mech->request( $req, $content_type ); |
39 | cmp_ok( $mech->status, '==', 400, |
40 | 'Attempt with invalid track id caught' ); |
41 | |
42 | my $response = $json->decode( $mech->content ); |
43 | like( |
44 | $response->{messages}->[0], |
45 | qr/No object found for id/, |
46 | 'correct message returned' |
47 | ); |
48 | |
49 | $track->discard_changes; |
50 | is_deeply( |
51 | { $track->get_columns }, |
52 | \%original_cols, |
53 | 'no update occurred' |
54 | ); |
55 | } |
d2739840 |
56 | } |
57 | |
58 | # validation when no params sent |
59 | { |
0b0bf911 |
60 | my $req = POST( $track_update_url, { wrong_param => 'value' } ); |
61 | $mech->request( $req, $content_type ); |
62 | cmp_ok( $mech->status, '==', 400, 'Update with no keys causes error' ); |
63 | |
64 | my $response = $json->decode( $mech->content ); |
65 | is_deeply( $response->{messages}, ['No valid keys passed'], |
66 | 'correct message returned' ); |
67 | |
68 | $track->discard_changes; |
69 | is_deeply( |
70 | { $track->get_columns }, |
71 | \%original_cols, |
72 | 'no update occurred' |
73 | ); |
d2739840 |
74 | } |
75 | |
76 | { |
0b0bf911 |
77 | my $req = POST( $track_update_url, { wrong_param => 'value' } ); |
78 | $mech->request( $req, $content_type ); |
79 | cmp_ok( $mech->status, '==', 400, 'Update with no keys causes error' ); |
80 | |
81 | my $response = $json->decode( $mech->content ); |
82 | is_deeply( $response->{messages}, ['No valid keys passed'], |
83 | 'correct message returned' ); |
84 | |
85 | $track->discard_changes; |
86 | is_deeply( |
87 | { $track->get_columns }, |
88 | \%original_cols, |
89 | 'no update occurred' |
90 | ); |
d2739840 |
91 | } |
92 | |
93 | { |
0b0bf911 |
94 | my $req = POST( $track_update_url, { title => undef } ); |
95 | $mech->request( $req, $content_type ); |
96 | cmp_ok( $mech->status, '==', 200, 'Update with key with no value okay' ); |
97 | |
98 | $track->discard_changes; |
99 | isnt( $track->title, $original_cols{title}, 'Title changed' ); |
100 | is( $track->title, '', 'Title changed to undef' ); |
d2739840 |
101 | } |
102 | |
103 | { |
0b0bf911 |
104 | my $req = POST( $track_update_url, { title => 'monkey monkey' } ); |
105 | $mech->request( $req, $content_type ); |
106 | cmp_ok( $mech->status, '==', 200, 'Update with key with value okay' ); |
107 | |
108 | $track->discard_changes; |
109 | is( $track->title, 'monkey monkey', 'Title changed to "monkey monkey"' ); |
d2739840 |
110 | } |
111 | |
112 | { |
0b0bf911 |
113 | my $req = POST( |
114 | $track_update_url, |
115 | { title => 'sheep sheep', |
116 | 'cd.year' => '2009' |
117 | } |
118 | ); |
119 | $mech->request( $req, $content_type ); |
120 | cmp_ok( $mech->status, '==', 200, |
121 | 'Update with key with value and related key okay' ); |
122 | |
123 | $track->discard_changes; |
124 | is( $track->title, 'sheep sheep', 'Title changed' ); |
125 | is( $track->cd->year, '2009', 'Related field changed"' ); |
d2739840 |
126 | } |
127 | |
128 | { |
88b67dcd |
129 | my $test_data = $json->encode( |
130 | { name => 'Caterwauler B. McCrae', |
131 | cds => [ |
132 | { |
133 | cdid => 1, |
134 | title => 'All the bees are gone', |
135 | year => 3030, |
136 | }, |
137 | { |
138 | cdid => 2, |
139 | title => 'All the crops are gone', |
140 | year => 3031 |
141 | } |
142 | ] |
143 | } |
144 | ); |
145 | |
146 | my $req = POST( $artist_update_url, Content => $test_data ); |
147 | $req->content_type('text/x-json'); |
148 | $mech->request($req); |
149 | |
150 | cmp_ok( $mech->status, '==', 200, 'Multi-row update returned 200 OK' ); |
151 | |
152 | my $artist = $schema->resultset('Artist')->search({ artistid => 1 }); |
153 | ok ($artist->next->name eq "Caterwauler B. McCrae", "mutliple related row parent record update"); |
154 | |
155 | # make sure the old cds don't exist, it's possible we just inserted the new rows instead of updating them |
156 | my $old_cds = $artist->search_related('cds', { title => ['Spoonful of bees', 'Forkful of bees'] } )->count; |
157 | ok ($old_cds == 0, 'update performed update and not create on related rows'); |
158 | |
159 | my @cds = $artist->search_related('cds', { year => ['3030', '3031'] }, { order_by => 'year' })->all; |
160 | ok (@cds == 2, 'update modified proper number of related rows'); |
161 | ok ($cds[0]->title eq 'All the bees are gone', 'update modified column on related row'); |
162 | ok ($cds[1]->title eq 'All the crops are gone', 'update modified column on second related row'); |
163 | } |
164 | |
165 | # update related rows using only unique_constraint on CD vs. primary key |
166 | # update the year on constraint match |
167 | { |
168 | my $test_data = $json->encode( |
169 | { name => 'Caterwauler McCrae', |
170 | cds => [ |
171 | { |
172 | artist => 1, |
173 | title => 'All the bees are gone', |
174 | year => 3032, |
175 | }, |
176 | { |
177 | artist => 1, |
178 | title => 'All the crops are gone', |
179 | year => 3032 |
180 | } |
181 | ] |
182 | } |
183 | ); |
184 | |
185 | my $req = POST( $artist_update_url, Content => $test_data ); |
186 | $req->content_type('text/x-json'); |
187 | $mech->request($req); |
188 | |
189 | cmp_ok( $mech->status, '==', 200, 'Multi-row unique constraint update returned 200 OK' ); |
190 | |
191 | my $artist = $schema->resultset('Artist')->search({ artistid => 1 }); |
192 | ok ($artist->next->name eq "Caterwauler McCrae", "multi-row unique constraint related row parent record updated"); |
193 | |
194 | my $old_cds = $artist->search_related('cds', { year => ['3030', '3031'] }, { order_by => 'year' })->count; |
195 | ok ( $old_cds == 0, 'multi-row update with unique constraint updated year' ); |
196 | |
197 | my $cds = $artist->search_related('cds', { 'year' => 3032 } )->count; |
198 | ok ( $cds == 2, 'multi-row update with unique constraint okay' ); |
199 | } |
200 | |
201 | { |
0b0bf911 |
202 | my $req = POST( $any_track_update_url, { title => 'baa' } ); |
203 | $mech->request( $req, $content_type ); |
204 | cmp_ok( $mech->status, '==', 200, 'Stash update okay' ); |
205 | |
206 | $track->discard_changes; |
207 | is( $track->title, 'baa', 'Title changed' ); |
d2739840 |
208 | } |
209 | |
210 | { |
0b0bf911 |
211 | my $req = POST( $any_track_update_url, { position => '14' } ); |
212 | $mech->request( $req, $content_type ); |
213 | cmp_ok( $mech->status, '==', 200, 'Position update okay' ); |
214 | |
215 | $track->discard_changes; |
216 | is( $track->get_column('position'), '14', 'Position changed' ); |
d2739840 |
217 | } |
218 | |
88b67dcd |
219 | |
7c8cb609 |
220 | # bulk_update existing objects |
0b8c7370 |
221 | { |
0b0bf911 |
222 | |
223 | # order to get a stable order of rows |
224 | my $tracks_rs = |
225 | $schema->resultset('Track') |
226 | ->search( undef, { order_by => 'trackid', rows => 3 } ); |
227 | my $test_data = $json->encode( |
228 | { list => [ |
229 | map +{ id => $_->id, title => 'Track ' . $_->id }, |
230 | $tracks_rs->all |
231 | ] |
232 | } |
233 | ); |
234 | my $req = POST( $tracks_update_url, Content => $test_data ); |
235 | $req->content_type('text/x-json'); |
236 | $mech->request($req); |
237 | cmp_ok( $mech->status, '==', 200, 'Attempt to update three tracks ok' ); |
238 | |
239 | $tracks_rs->reset; |
240 | while ( my $track = $tracks_rs->next ) { |
241 | is( $track->title, 'Track ' . $track->id, 'Title changed' ); |
242 | } |
0b8c7370 |
243 | } |
244 | |
7c8cb609 |
245 | # bulk_update nonexisting objects |
246 | { |
0b0bf911 |
247 | |
248 | # order to get a stable order of rows |
249 | my $test_data = $json->encode( |
250 | { list => [ |
251 | map +{ id => $_, title => 'Track ' . $_ }, |
252 | ( 1000 .. 1002 ) |
253 | ] |
254 | } |
255 | ); |
256 | my $req = POST( $tracks_update_url, Content => $test_data ); |
257 | $req->content_type('text/x-json'); |
258 | $mech->request($req); |
259 | cmp_ok( $mech->status, '==', 400, |
260 | 'Attempt to update three nonexisting tracks fails' ); |
261 | my $response = $json->decode( $mech->content ); |
262 | is( $response->{success}, 'false', |
263 | 'success property returns quoted false' ); |
264 | like( |
265 | $response->{messages}->[0], |
266 | qr/No object found for id/, |
267 | 'correct message returned' |
268 | ); |
7c8cb609 |
269 | } |
270 | |
d2739840 |
271 | done_testing(); |