fix ticketing system error on bootstrap of new install
[freeside.git] / rt / t / web / rest.t
1 use strict;
2 use warnings;
3 use RT::Interface::REST;
4
5 use RT::Test tests => 34;
6
7 my ($baseurl, $m) = RT::Test->started_ok;
8
9 for my $name ("severity", "fu()n:k/") {
10     my $cf = RT::Test->load_or_create_custom_field(
11         Name  => $name,
12         Type  => 'FreeformMultiple',
13         Queue => 'General',
14     );
15     ok($cf->Id, "created a CustomField");
16     is($cf->Name, $name, "correct CF name");
17 }
18 {
19     my $cf = RT::Test->load_or_create_custom_field(
20         Name  => 'single',
21         Type  => 'FreeformSingle',
22         Queue => 'General',
23     );
24     ok($cf->Id, "created a CustomField");
25 }
26
27 my $queue = RT::Test->load_or_create_queue(Name => 'General');
28 ok($queue->Id, "loaded the General queue");
29
30 $m->post("$baseurl/REST/1.0/ticket/new", [
31     user    => 'root',
32     pass    => 'password',
33     format  => 'l',
34 ]);
35
36 my $text = $m->content;
37 my @lines = $text =~ m{.*}g;
38 shift @lines; # header
39
40 # CFs aren't in the default ticket form
41 push @lines, "CF-fu()n:k/: maximum"; # old style
42 push @lines, "CF.{severity}: explosive"; # new style
43
44 $text = join "\n", @lines;
45
46 ok($text =~ s/Subject:\s*$/Subject: REST interface/m, "successfully replaced subject");
47
48 $m->post("$baseurl/REST/1.0/ticket/edit", [
49     user    => 'root',
50     pass    => 'password',
51
52     content => $text,
53 ], Content_Type => 'form-data');
54
55 my ($id) = $m->content =~ /Ticket (\d+) created/;
56 ok($id, "got ticket #$id");
57
58 my $ticket = RT::Ticket->new(RT->SystemUser);
59 $ticket->Load($id);
60 is($ticket->Id, $id, "loaded the REST-created ticket");
61 is($ticket->Subject, "REST interface", "subject successfully set");
62 is($ticket->FirstCustomFieldValue("fu()n:k/"), "maximum", "CF successfully set");
63
64 $m->post("$baseurl/REST/1.0/search/ticket", [
65     user    => 'root',
66     pass    => 'password',
67     query   => "id=$id",
68     fields  => "Subject,CF-fu()n:k/,CF.{severity},Status",
69 ]);
70
71 # the fields are interpreted server-side a hash (why?), so we can't depend
72 # on order
73 for ("id: ticket/1",
74      "Subject: REST interface",
75      "CF.{fu()n:k/}: maximum",
76      "CF.{severity}: explosive",
77      "Status: new") {
78         $m->content_contains($_);
79 }
80
81 # Create ticket 2 for testing ticket links
82 for (2 .. 3) {
83     $m->post("$baseurl/REST/1.0/ticket/edit", [
84         user    => 'root',
85         pass    => 'password',
86         content => $text,
87     ], Content_Type => 'form-data');
88
89     $m->post(
90         "$baseurl/REST/1.0/ticket/1/links",
91         [
92             user    => 'root',
93             pass    => 'password',
94         ],
95         Content_Type => 'form-data',
96     );
97
98     my $link_data = form_parse($m->content);
99
100     push @{$link_data->[0]->[1]}, 'DependsOn';
101     vpush($link_data->[0]->[2], 'DependsOn', $_);
102
103     $m->post(
104         "$baseurl/REST/1.0/ticket/1/links",
105         [
106             user    => 'root',
107             pass    => 'password',
108             content => form_compose($link_data),
109         ],
110         Content_Type => 'form-data',
111     );
112
113 }
114
115 # See what links get reported for ticket 1.
116 $m->post(
117     "$baseurl/REST/1.0/ticket/1/links/show",
118     [
119         user    => 'root',
120         pass    => 'password',
121     ],
122     Content_Type => 'form-data',
123 );
124
125 # Verify that the link was added correctly.
126 my $content = form_parse($m->content);
127 my $depends_on = vsplit($content->[0]->[2]->{DependsOn});
128 @$depends_on = sort @$depends_on;
129 like(
130     $depends_on->[0], qr{/ticket/2$},
131     "Check ticket link.",
132 ) or diag("'content' obtained:\n", $m->content);
133
134 like(
135     $depends_on->[1], qr{/ticket/3$},
136     "Check ticket link.",
137 ) or diag("'content' obtained:\n", $m->content);
138
139 $m->post(
140     "$baseurl/REST/1.0/ticket/2/links/show",
141     [
142         user    => 'root',
143         pass    => 'password',
144     ],
145     Content_Type => 'form-data',
146 );
147 my ($link) = $m->content =~ m|DependedOnBy:.*ticket/(\d+)|;
148 is($link, 1, "Check ticket link.") or diag("'content' obtained:\n", $m->content);
149
150 $m->post(
151     "$baseurl/REST/1.0/ticket/3/links/show",
152     [
153         user    => 'root',
154         pass    => 'password',
155     ],
156     Content_Type => 'form-data',
157 );
158 ($link) = $m->content =~ m|DependedOnBy:.*ticket/(\d+)|;
159 is($link, 1, "Check ticket link.") or diag("'content' obtained:\n", $m->content);
160
161
162 {
163     $m->post("$baseurl/REST/1.0/ticket/new", [
164         user    => 'root',
165         pass    => 'password',
166         format  => 'l',
167     ]);
168
169     my $text = $m->content;
170     my @lines = $text =~ m{.*}g;
171     shift @lines; # header
172     push @lines, "CF.{severity}: explosive";
173     push @lines, "CF.{severity}: very";
174     $text = join "\n", @lines;
175
176     $m->post("$baseurl/REST/1.0/ticket/edit", [
177         user    => 'root',
178         pass    => 'password',
179
180         content => $text,
181     ], Content_Type => 'form-data');
182
183     my ($id) = $m->content =~ /Ticket (\d+) created/;
184     ok($id, "got ticket #$id");
185
186     my $ticket = RT::Ticket->new(RT->SystemUser);
187     $ticket->Load($id);
188     is($ticket->Id, $id, "loaded the REST-created ticket");
189     is_deeply(
190         [sort map $_->Content, @{ $ticket->CustomFieldValues("severity")->ItemsArrayRef }],
191         ["explosive", "very"],
192         "CF successfully set"
193     );
194
195     $m->post(
196         "$baseurl/REST/1.0/ticket/show",
197         [
198             user   => 'root',
199             pass   => 'password',
200             format => 'l',
201             id     => "ticket/$id",
202         ]
203     );
204     $text = $m->content;
205     $text =~ s/.*?\n\n//;
206     $text =~ s/\n\n/\n/;
207     $text =~ s{CF\.\{severity\}:.*\n}{}img;
208     $text .= "CF.{severity}: explosive, a bit\n";
209     $m->post(
210         "$baseurl/REST/1.0/ticket/edit",
211         [
212             user => 'root',
213             pass => 'password',
214             content => $text,
215         ],
216         Content_Type => 'form-data'
217     );
218     $m->content =~ /Ticket ($id) updated/;
219
220     $ticket->Load($id);
221     is_deeply(
222         [sort map $_->Content, @{ $ticket->CustomFieldValues("severity")->ItemsArrayRef }],
223         ['a bit', 'explosive'],
224         "CF successfully set"
225     );
226
227     $m->post(
228         "$baseurl/REST/1.0/ticket/show",
229         [
230             user   => 'root',
231             pass   => 'password',
232             format => 'l',
233             id     => "ticket/$id",
234         ]
235     );
236     $text = $m->content;
237     $text =~ s{CF\.\{severity\}:.*\n}{}img;
238     $text .= "CF.{severity}:\n";
239     $m->post(
240         "$baseurl/REST/1.0/ticket/edit",
241         [
242             user => 'root',
243             pass => 'password',
244             content => $text,
245         ],
246         Content_Type => 'form-data'
247     );
248     $m->content =~ /Ticket ($id) updated/;
249
250     $ticket->Load($id);
251     is_deeply(
252         [sort map $_->Content, @{ $ticket->CustomFieldValues("severity")->ItemsArrayRef }],
253         [],
254         "CF successfully set"
255     );
256
257     my @txns = map [$_->OldValue, $_->NewValue], grep $_->Type eq 'CustomField',
258         @{ $ticket->Transactions->ItemsArrayRef };
259     is_deeply(\@txns, [['very', undef], [undef, 'a bit'], ['explosive', undef], ['a bit', undef]]);
260 }
261
262 {
263     $m->post("$baseurl/REST/1.0/ticket/new", [
264         user    => 'root',
265         pass    => 'password',
266         format  => 'l',
267     ]);
268
269     my $text = $m->content;
270     my @lines = $text =~ m{.*}g;
271     shift @lines; # header
272     push @lines, "CF.{single}: this";
273     $text = join "\n", @lines;
274
275     $m->post("$baseurl/REST/1.0/ticket/edit", [
276         user    => 'root',
277         pass    => 'password',
278
279         content => $text,
280     ], Content_Type => 'form-data');
281
282     my ($id) = $m->content =~ /Ticket (\d+) created/;
283     ok($id, "got ticket #$id");
284
285     my $ticket = RT::Ticket->new(RT->SystemUser);
286     $ticket->Load($id);
287     is($ticket->Id, $id, "loaded the REST-created ticket");
288     is_deeply(
289         [sort map $_->Content, @{ $ticket->CustomFieldValues("single")->ItemsArrayRef }],
290         ["this"],
291         "CF successfully set"
292     );
293
294     $m->post(
295         "$baseurl/REST/1.0/ticket/show",
296         [
297             user   => 'root',
298             pass   => 'password',
299             format => 'l',
300             id     => "ticket/$id",
301         ]
302     );
303     $text = $m->content;
304     $text =~ s{CF\.\{single\}:.*\n}{}img;
305     $text .= "CF.{single}: that\n";
306     $m->post(
307         "$baseurl/REST/1.0/ticket/edit",
308         [
309             user => 'root',
310             pass => 'password',
311             content => $text,
312         ],
313         Content_Type => 'form-data'
314     );
315     $m->content =~ /Ticket ($id) updated/;
316
317     $ticket->Load($id);
318     is_deeply(
319         [sort map $_->Content, @{ $ticket->CustomFieldValues("single")->ItemsArrayRef }],
320         ['that'],
321         "CF successfully set"
322     );
323
324     my @txns = map [$_->OldValue, $_->NewValue], grep $_->Type eq 'CustomField',
325         @{ $ticket->Transactions->ItemsArrayRef };
326     is_deeply(\@txns, [['this', 'that']]);
327 }