]> git.imager.perl.org - bse.git/blame - t/080-remote/010-save.t
update the required modules list
[bse.git] / t / 080-remote / 010-save.t
CommitLineData
8f88bb20
TC
1#!perl -w
2use strict;
bf149413 3use BSE::Test qw(make_ua base_url);
8f88bb20
TC
4use JSON;
5use DevHelp::HTML;
425b90a6
TC
6use Test::More;
7use Article;
8
9my @cols = Article->columns;
10
dbfbfb12 11my $base = 119;
425b90a6 12
b16d2b32 13my $count = $base + (@cols - 13) * 4;
425b90a6
TC
14
15plan tests => $count;
76c6b28e
TC
16
17$| = 1;
8f88bb20 18
8f88bb20
TC
19my $ua = make_ua;
20my $baseurl = base_url;
21
22my $add_url = $baseurl . "/cgi-bin/admin/add.pl";
23
24my @ajax_hdr = qw(X-Requested-With: XMLHttpRequest);
25
bf149413
TC
26my %add_req =
27 (
28 save => 1,
29 title => "test",
30 parentid => -1,
7350b200 31 _context => "test context",
bf149413
TC
32 );
33my $art_data = do_req($add_url, \%add_req, "add article");
8f88bb20 34
bf149413
TC
35SKIP:
36{
37 $art_data or skip("no response to add", 20);
38 ok($art_data->{success}, "successful json response");
8f88bb20 39
7350b200
TC
40 is($art_data->{context}, "test context", "check context returned");
41
bf149413
TC
42 my $art = $art_data->{article};
43 my $orig_lastmod = $art->{lastModified};
8f88bb20 44
bf149413
TC
45 # try to fetch by id
46 SKIP:
8f88bb20 47 {
bf149413
TC
48 my %fetch_req =
49 (
50 a_article => 1,
51 id => $art->{id},
52 );
53 my $data = do_req($add_url, \%fetch_req, "fetch just saved")
54 or skip("no json", 2);
55 ok($data->{success}, "successful");
56 ok($data->{article}, "has an article");
57 my %temp = %$art;
58 for my $field (qw/release expire/) {
59 delete $temp{$field};
60 delete $data->{article}{$field};
61 }
62 is_deeply($data->{article}, \%temp, "check it matches what we saved");
76c6b28e
TC
63 ok($data->{article}{tags}, "has a tags member");
64 is_deeply($data->{article}{tags}, [], "which is an empty array ref");
bf149413
TC
65 }
66
67 my @fields = grep
68 {
69 defined $art->{$_}
70 && !/^(id|created|link|admin|files|images|cached_dynamic|createdBy|generator|level|lastModified(By)?|displayOrder)$/
71 && !/^thumb/
72 } keys %$art;
73
74 for my $field (@fields) {
75 print "# save test $field\n";
76 my %reqdata =
77 (
78 save => 1,
79 id => $art->{id},
80 $field => $art->{$field},
81 lastModified => $art->{lastModified},
82 );
83 my $data = do_req($add_url, \%reqdata, "set $field");
84 SKIP:
85 {
86 $data or skip("Not json from setting $field", 2);
87 ok($data->{success}, "success flag is set");
88 ok($data->{article}, "has an article object");
89 $art = $data->{article};
90 }
91 }
92
dbfbfb12
TC
93 { # try to set a bad value for category
94 my %req_data =
95 (
96 save => 1,
97 id => $art->{id},
98 category => "A" . rand(),
99 lastModified => $art->{lastModified},
100 );
101 my $data = do_req($add_url, \%req_data, "save bad category");
102 SKIP:
103 {
104 $data or skip("Not json from setting bad category", 4);
105 ok(!$data->{success}, "shouldn't be successful");
106 ok(!$data->{article}, "should be no article object");
107 is($data->{error_code}, "FIELD", "should be a field error");
108 ok($data->{errors} && $data->{errors}{category},
109 "should be an error message for category");
110 }
111 }
112
76c6b28e
TC
113 my $tag_name1 = "YHUIOP";
114 my $tag_name2 = "zyx: alpha";
115 { # save tags
116 my %reqdata =
117 (
118 save => 1,
119 id => $art->{id},
120 _save_tags => 1,
121 tags => [ $tag_name2, " $tag_name1 " ],
122 lastModified => $art->{lastModified},
123 );
124 my $data = do_req($add_url, \%reqdata, "set tags");
125 SKIP:
126 {
127 $data or skip("Not json from setting tags", 2);
128 ok($data->{success}, "success flag set");
129 is_deeply($data->{article}{tags}, [ $tag_name1, $tag_name2 ],
130 "check tags saved");
131 $art = $data->{article};
132 }
133 }
134
66acec63
TC
135 { # grab the tree
136 my %tree_req =
137 (
138 a_tree => 1,
139 id => -1,
140 );
141 my $data = do_req($add_url, \%tree_req, "fetch tree");
142 $data or skip("not a json response", 6);
143 ok($data->{success}, "was successful");
144 ok($data->{articles}, "has articles");
145 my $art = $data->{articles}[0];
146 ok(defined $art->{level}, "entries have level");
147 ok($art->{title}, "entries have a title");
148 ok(defined $art->{listed}, "entries have a listed");
149 ok($art->{lastModified}, "entries have a lastModified");
150 }
151
76c6b28e
TC
152 { # grab the tags
153 my %tag_req =
154 (
155 a_tags => 1,
156 id => -1,
157 );
158 my $data = do_req($add_url, \%tag_req, "fetch tags");
159 SKIP:
160 {
161 $data or skip("not a json response", 4);
162 ok($data->{tags}, "it has tags");
163 my ($xyz_tag) = grep $_->{name} eq $tag_name2, @{$data->{tags}};
164 ok($xyz_tag, "check we found the tag we set");
165 is($xyz_tag->{cat}, "zyx", "check cat");
166 is($xyz_tag->{val}, "alpha", "check val");
167 }
168 }
169
170 my $tag1;
171 my $tag2;
172 { # grab them with article ids
173 my %tag_req =
174 (
175 a_tags => 1,
176 id => -1,
177 showarts => 1,
178 );
179 my $data = do_req($add_url, \%tag_req, "fetch tags");
180 SKIP:
181 {
182 $data or skip("not a json response", 6);
183 ok($data->{tags}, "it has tags");
184 ($tag1) = grep $_->{name} eq $tag_name1, @{$data->{tags}};
185 ($tag2) = grep $_->{name} eq $tag_name2, @{$data->{tags}};
186 ok($tag2, "check we found the tag we set");
187 is($tag2->{cat}, "zyx", "check cat");
188 is($tag2->{val}, "alpha", "check val");
189 ok($tag2->{articles}, "has articles");
190 ok(grep($_ == $art->{id}, @{$tag2->{articles}}),
191 "has our article id in it");
192 }
193 }
194
195 SKIP:
196 { # delete a tag globally
197 $tag2
198 or skip("didn't find the tag we want to remove", 6);
199 my %del_req =
200 (
201 a_tagdelete => 1,
202 id => -1,
203 tag_id => $tag2->{id},
204 );
205 my $data = do_req($add_url, \%del_req, "delete tag");
206 SKIP:
207 {
208 $data or skip("not a json response", 7);
209 ok($data->{success}, "successful");
210
211 # refetch tag list and make sure it's gone
212 my %get_req =
213 (
214 a_tags => 1,
215 id => -1,
216 );
217 my $tags_data = do_req($add_url, \%get_req, "refetch tags");
218 my ($tag) = grep $_->{name} eq $tag_name2, @{$data->{tags}};
219 ok(!$tag, "should be gone");
220
221 # try to delete it again
222 my $redel_data = do_req($add_url, \%del_req, "delete should fail");
223 $redel_data
224 or skip("not a json response", 3);
225 ok(!$redel_data->{success}, "should fail");
226 is($redel_data->{error_code}, "FIELD", "check error code");
227 ok($redel_data->{errors}{tag_id}, "and error message on field");
228 }
229 }
230
231 { # rename a tag
232 my %ren_req =
233 (
234 a_tagrename => 1,
235 id => -1,
236 tag_id => $tag1->{id},
237 name => $tag_name2, # rename over just removed tag
238 );
239
240 my $data = do_req($add_url, \%ren_req, "rename tag");
241 SKIP:
242 {
243 $data
244 or skip("not a json response", 4);
245 ok($data->{success}, "successful");
246 ok($data->{tag}, "returned updated tag");
247 is($data->{tag}{name}, $tag_name2, "check name saved");
248 }
249 }
250
251 { # refetch the article to check the tags
252 my %fetch_req =
253 (
254 a_article => 1,
255 id => $art->{id},
256 );
257 my $data = do_req($add_url, \%fetch_req, "fetch just saved")
258 or skip("no json", 2);
259 ok($data->{success}, "check success");
260 is_deeply($data->{article}{tags}, [ $tag_name2 ],
261 "check the tags");
262 }
263
bf149413
TC
264 # error handling on save
265 SKIP:
266 { # bad title
267 my %bad_title =
268 (
269 save => 1,
270 id => $art->{id},
271 title => "",
272 lastModified => $art->{lastModified},
273 );
274 my $data = do_req($add_url, \%bad_title, "save bad title");
275 $data or skip("not a json response", 2);
276 ok(!$data->{success}, "should be failure");
277 is($data->{error_code}, "FIELD", "should be a field error");
278 ok($data->{errors}{title}, "should be a message for the title");
279 }
280 SKIP:
281 { # bad template
282 my %bad_template =
283 (
284 save => 1,
285 id => $art->{id},
286 template => "../../etc/passwd",
287 lastModified => $art->{lastModified},
288 );
289 my $data = do_req($add_url, \%bad_template, "save bad template");
290 $data or skip("not a json response", 2);
291 ok(!$data->{success}, "should be failure");
292 is($data->{error_code}, "FIELD", "should be a field error");
293 ok($data->{errors}{template}, "should be a message for the template");
294 }
295 SKIP:
296 { # bad last modified
297 my %bad_lastmod =
298 (
299 save => 1,
300 id => $art->{id},
301 title => "test",
302 lastModified => $orig_lastmod,
303 );
304 my $data = do_req($add_url, \%bad_lastmod, "save bad lastmod");
305 $data or skip("not a json response", 2);
306 ok(!$data->{success}, "should be failure");
307 is($data->{error_code}, "LASTMOD", "should be a last mod error");
308 }
309 SKIP:
310 { # bad parent
311 my %bad_parent =
312 (
313 save => 1,
314 id => $art->{id},
315 parentid => $art->{id},
316 lastModified => $art->{lastModified},
317 );
318 my $data = do_req($add_url, \%bad_parent, "save bad parent");
319 $data or skip("not a json response", 2);
320 ok(!$data->{success}, "should be failure");
321 is($data->{error_code}, "PARENT", "should be a parent error");
322 }
d62f54f7
TC
323
324 # grab config data for the article
325 SKIP:
326 {
327 my %conf_req =
328 (
329 a_config => 1,
330 id => $art->{id},
331 );
332 my $data = do_req($add_url, \%conf_req, "config data");
ff234bfa 333 $data or skip("no json to check", 7);
d62f54f7
TC
334 ok($data->{success}, "check for success");
335 ok($data->{templates}, "has templates");
336 ok($data->{thumb_geometries}, "has geometries");
337 ok($data->{defaults}, "has defaults");
338 ok($data->{child_types}, "has child types");
339 is($data->{child_types}[0], "Article", "check child type value");
ff234bfa 340 ok($data->{flags}, "has flags");
d62f54f7
TC
341 }
342
343 SKIP:
344 { # config article for children of the article
345 my %conf_req =
346 (
347 a_config => 1,
348 parentid => $art->{id},
349 );
350 my $data = do_req($add_url, \%conf_req, "config data");
351 $data or skip("no json to check", 3);
352 ok($data->{success}, "check for success");
353 ok($data->{templates}, "has templates");
354 ok($data->{thumb_geometries}, "has geometries");
355 ok($data->{defaults}, "has defaults");
356 }
357
358 SKIP:
359 { # section config
360 my %conf_req =
361 (
362 a_config => 1,
363 parentid => -1,
364 );
365 my $data = do_req($add_url, \%conf_req, "section config data");
366 $data or skip("no json to check", 3);
367 ok($data->{success}, "check for success");
368 ok($data->{templates}, "has templates");
369 ok($data->{thumb_geometries}, "has geometries");
370 ok($data->{defaults}, "has defaults");
371 use Data::Dumper;
372 note(Dumper($data));
373 }
bf149413 374
78218ca8
TC
375 SKIP:
376 {
377 my $parent = do_add($add_url, { parentid => -1, title => "parent" }, "add parent");
378 my $kid1 = do_add($add_url, { parentid => $parent->{id}, title => "kid1" }, "add first kid");
379 sleep 2;
380 my $kid2 = do_add($add_url,
381 {
382 parentid => $parent->{id},
383 title => "kid2",
384 _after => $kid1->{id},
385 }, "add second child");
386 my @expected_order = ( $kid1->{id}, $kid2->{id} );
387 my %tree_req =
388 (
389 a_tree => 1,
390 id => $parent->{id},
391 );
392 my $data = do_req($add_url, \%tree_req, "get newly ordered tree");
393 ok($data->{success}, "got the tree");
394 my @saved_order = map $_->{id}, @{$data->{articles}};
395 is_deeply(\@saved_order, \@expected_order, "check saved order");
0b2a3da0
TC
396
397 {
398 {
399 # stepkids
400 my %add_step =
401 (
402 add_stepkid => 1,
403 id => $parent->{id},
404 stepkid => $art->{id},
405 _after => $kid1->{id},
406 );
407 sleep(2);
408 my $result = do_req($add_url, \%add_step, "add stepkid in order");
409 ok($result->{success}, "Successfully");
410 my $rel = $result->{relationship};
411 ok($rel, "has a relationship");
412 is($rel->{childId}, $art->{id}, "check the rel child id");
413 is($rel->{parentId}, $parent->{id}, "check the rel parent id");
414 }
415
416 {
417 # refetch the tree
418 my $data = do_req($add_url, \%tree_req, "get tree with stepkid");
419 my @expected_order = ( $kid1->{id}, $art->{id}, $kid2->{id} );
420 my @found_order = map $_->{id}, @{$data->{allkids}};
421 is_deeply(\@found_order, \@expected_order, "check new order");
422 }
423
424 {
425 # remove the stepkid
426 my %del_step =
427 (
428 del_stepkid => 1,
429 id => $parent->{id},
430 stepkid => $art->{id},
431 _after => $kid1->{id},
432 );
433 my $result = do_req($add_url, \%del_step, "delete stepkid");
434 ok($result->{success}, "check success");
435
436 $result = do_req($add_url, \%del_step, "delete stepkid again (should failed)");
437 ok(!$result->{success}, "it failed");
438
439 my $data = do_req($add_url, \%tree_req, "get tree with stepkid removed");
440 my @expected_order = ( $kid1->{id}, $kid2->{id} );
441 my @found_order = map $_->{id}, @{$data->{allkids}};
442 is_deeply(\@found_order, \@expected_order, "check new order with stepkid removed");
443 }
444 }
445
78218ca8
TC
446 do_req($add_url, { remove => 1, id => $kid1->{id} }, "remove kid1");
447 do_req($add_url, { remove => 1, id => $kid2->{id} }, "remove kid2");
448 do_req($add_url, { remove => 1, id => $parent->{id} }, "remove parent");
449 }
450
bf149413
TC
451 # delete it
452 SKIP:
453 {
454 my %del_req =
455 (
456 remove => 1,
457 id => $art->{id},
7350b200 458 _context => $art->{id},
bf149413
TC
459 );
460 my $data = do_req($add_url, \%del_req, "remove test article");
7350b200 461 $data or skip("no json from req", 3);
bf149413 462 ok($data->{success}, "successfully deleted");
107c0225 463 is($data->{article_id}, $art->{id}, "check id returned");
7350b200 464 is($data->{context}, $art->{id}, "check context returned");
bf149413
TC
465 }
466
467 # shouldn't be fetchable anymore
468 SKIP:
469 {
470 my %fetch_req =
471 (
472 a_article => 1,
473 id => $art->{id},
474 );
475 my $data = do_req($add_url, \%fetch_req, "fetch just deleted")
476 or skip("no json", 2);
477 ok(!$data->{success}, "failed as expected");
478 }
479}
480
76c6b28e
TC
481SKIP:
482{ # tag cleanup
483 my %clean_req =
484 (
485 a_tagcleanup => 1,
486 id => -1,
487 );
488 my $data = do_req($add_url, \%clean_req, "tag cleanup");
489 $data
490 or skip("no json response", 2);
491 ok($data->{success}, "successful");
492 ok($data->{count}, "should have cleaned up something");
493}
494
bf149413
TC
495sub do_req {
496 my ($url, $req_data, $comment) = @_;
497
76c6b28e
TC
498 my @entries;
499 for my $key (keys %$req_data) {
500 my $value = $req_data->{$key};
501 if (ref $value) {
502 for my $val (@$value) {
503 push @entries, "$key=" . escape_uri($val);
504 }
505 }
506 else {
507 push @entries, "$key=" . escape_uri($value);
508 }
509 }
510 my $content = join("&", @entries);
511
512 print <<EOS;
513# Request:
514# URL: $add_url
515# Content: $content
516EOS
517
8f88bb20
TC
518 my $req = HTTP::Request->new(POST => $add_url, \@ajax_hdr);
519
520 $req->content($content);
76c6b28e 521
8f88bb20 522 my $resp = $ua->request($req);
bf149413 523 ok($resp->is_success, "$comment successful at http level");
8f88bb20 524 my $data = eval { from_json($resp->decoded_content) };
bf149413
TC
525 ok($data, "$comment response decoded as json")
526 or print "# $@\n";
527
528 return $data;
8f88bb20 529}
78218ca8
TC
530
531sub do_add {
532 my ($url, $req, $comment) = @_;
533
534 $req->{save} = 1;
535
536 my $result = do_req($url, $req, $comment);
537 my $article;
538 SKIP:
539 {
540 $result or skip("No JSON result", 1);
541 if (ok($result->{success} && $result->{article}, "check success and article")) {
542 return $result->{article};
543 }
544 };
545
546 return;
547}