fix ticketing system error on bootstrap of new install
[freeside.git] / rt / t / api / customfield.t
1
2 use strict;
3 use warnings;
4 use RT;
5 use RT::Test tests => undef;
6 use Test::Warn;
7
8 use_ok('RT::CustomField');
9
10 my $queue = RT::Queue->new( RT->SystemUser );
11 $queue->Load( "General" );
12 ok( $queue->id, "found the General queue" );
13
14 my $cf = RT::CustomField->new(RT->SystemUser);
15 ok($cf, "Have a CustomField object");
16
17 # Use the old Queue field to set up a ticket CF
18 my ($ok, $msg) =  $cf->Create(
19     Name        => 'TestingCF',
20     Queue       => '0',
21     Description => 'A Testing custom field',
22     Type        => 'SelectSingle'
23 );
24 ok($ok, 'Global custom field correctly created');
25 is($cf->Type, 'Select', "Is a select CF");
26 ok($cf->SingleValue, "Also a single-value CF");
27 is($cf->MaxValues, 1, "...meaning only one value, max");
28
29 ($ok, $msg) = $cf->SetMaxValues('0');
30 ok($ok, "Set to infinite values: $msg");
31 is($cf->Type, 'Select', "Still a select CF");
32 ok( ! $cf->SingleValue, "No longer single-value" );
33 is($cf->MaxValues, 0, "...meaning no maximum values");
34
35 # Test our sanity checking of CF types
36 ($ok, $msg) = $cf->SetType('BogusType');
37 ok( ! $ok, "Unable to set a custom field's type to a bogus type: $msg");
38
39 $cf = RT::CustomField->new(RT->SystemUser);
40 ($ok, $msg) = $cf->Create(
41     Name => 'TestingCF-bad',
42     Queue => '0',
43     SortOrder => '1',
44     Description => 'A Testing custom field with a bogus Type',
45     Type=> 'SelectSingleton'
46 );
47 ok( ! $ok, "Correctly could not create with bogus type: $msg");
48
49
50 # Deprecated types
51 warning_like {
52     ok($cf->ValidateType('SelectSingle'), "ValidateType accepts SelectSingle");
53 } qr/deprecated/, "...but warns of deprecation";
54
55 warning_like {
56     ok($cf->ValidateType('SelectMultiple'), "ValidateType accepts SelectMultiple");
57 } qr/deprecated/, "...but warns of deprecation";
58
59 warning_like {
60     ok( ! $cf->ValidateType('SelectFooMultiple'), "ValidateType does not accept SelectFooMultiple");
61 } qr/deprecated/, "...and also warns of deprecation";
62
63
64 # Test adding and removing CFVs
65 $cf->Load(1);
66 ($ok, $msg) = $cf->AddValue(Name => 'foo' , Description => 'TestCFValue', SortOrder => '6');
67 ok($ok, "Added a new value to the select options");
68 ($ok, $msg) = $cf->DeleteValue($ok);
69 ok($ok, "Deleting it again");
70
71
72 # Loading, and context objects
73 $cf = RT::CustomField->new( RT->SystemUser );
74 $cf->LoadByName( Name => "TestingCF" );
75 ok($cf->id, "Load finds it, given just a name" );
76 ok( ! $cf->ContextObject, "Did not get a context object");
77
78 # Old Queue => form should find the global, gain no context object
79 $cf = RT::CustomField->new( RT->SystemUser );
80 $cf->LoadByName(Name => 'TestingCF', Queue => 0);
81 ok($cf->id, "Load finds it, given a Name and Queue => 0" );
82 ok( ! $cf->ContextObject, 'Context object not set when queue is 0');
83
84 # We don't default to also searching global -- but do pick up a contextobject
85 $cf = RT::CustomField->new( RT->SystemUser );
86 $cf->LoadByName(Name => 'TestingCF', Queue => 1);
87 ok( ! $cf->id, "Load does not finds it, given a Name and Queue => 1" );
88 ok($cf->ContextObject->id, 'Context object is now set');
89
90 # If we IncludeGlobal, we find it
91 $cf = RT::CustomField->new( RT->SystemUser );
92 $cf->LoadByName(Name => 'TestingCF', Queue => 1, IncludeGlobal => 1 );
93 ok($cf->id, "Load now finds it, given a Name and Queue => 1 and IncludeGlobal" );
94 ok($cf->ContextObject->id, 'Context object is also set');
95
96 # The explicit LookupType works
97 $cf = RT::CustomField->new( RT->SystemUser );
98 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType );
99 ok($cf->id, "Load now finds it, given a Name and LookupType" );
100 ok( ! $cf->ContextObject, 'No context object gained');
101
102 # The explicit LookupType, ObjectId, and IncludeGlobal -- what most folks want
103 $cf = RT::CustomField->new( RT->SystemUser );
104 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType,
105                 ObjectId => 1, IncludeGlobal => 1 );
106 ok($cf->id, "Load now finds it, given a Name, LookupType, ObjectId, IncludeGlobal" );
107 ok($cf->ContextObject->id, 'And gains a context obj');
108
109 # Look for a queue by name
110 $cf = RT::CustomField->new( RT->SystemUser );
111 $cf->LoadByName(Name => 'TestingCF', Queue => "General" );
112 ok( ! $cf->id, "No IncludeGlobal, so queue by name fails" );
113 ok($cf->ContextObject->id, 'But gains a context object');
114
115 # Look for a queue by name, include global
116 $cf = RT::CustomField->new( RT->SystemUser );
117 $cf->LoadByName(Name => 'TestingCF', Queue => "General", IncludeGlobal => 1 );
118 ok($cf->id, "By name, and queue name works with IncludeGlobal" );
119 ok($cf->ContextObject->id, 'And gains a context object');
120
121
122
123 # A bogus Queue gets you no results, but a warning
124 $cf = RT::CustomField->new( RT->SystemUser );
125 warning_like {
126     $cf->LoadByName(Name => 'TestingCF', Queue => "Bogus" );
127     ok( ! $cf->id, "With a bogus queue name gets no results" );
128     ok( ! $cf->ContextObject, 'And also no context object');
129 } qr/Failed to load RT::Queue 'Bogus'/, "Generates a warning";
130
131 # Ditto by number which is bogus
132 $cf = RT::CustomField->new( RT->SystemUser );
133 warning_like {
134     $cf->LoadByName(Name => 'TestingCF', Queue => "9000" );
135     ok( ! $cf->id, "With a bogus queue number gets no results" );
136     ok( ! $cf->ContextObject, 'And also no context object');
137 } qr/Failed to load RT::Queue '9000'/, "Generates a warning";
138
139 # But if they also wanted global results, we might have an answer
140 $cf = RT::CustomField->new( RT->SystemUser );
141 warning_like {
142     $cf->LoadByName(Name => 'TestingCF', Queue => "9000", IncludeGlobal => 1 );
143     ok($cf->id, "Bogus queue but IncludeGlobal founds it" );
144     ok( ! $cf->ContextObject, 'But no context object');
145 } qr/Failed to load RT::Queue '9000'/, "And generates a warning";
146
147
148 # Make it only apply to one queue
149 $cf->Load(1);
150 my $ocf = RT::ObjectCustomField->new( RT->SystemUser );
151 ( $ok, $msg ) = $ocf->LoadByCols( CustomField => $cf->id, ObjectId => 0 );
152 ok( $ok, "Found global application of CF" );
153 ( $ok, $msg ) = $ocf->Delete;
154 ok( $ok, "...and deleted it");
155 ( $ok, $msg ) = $ocf->Add( CustomField => $cf->id, ObjectId => 1 );
156 ok($ok, "Applied to just queue 1" );
157
158 # Looking for it globally with Queue => 0 should fail, gain no context object
159 $cf = RT::CustomField->new( RT->SystemUser );
160 $cf->LoadByName(Name => 'TestingCF', Queue => 0);
161 ok( ! $cf->id, "Load fails to find, given a Name and Queue => 0" );
162 ok( ! $cf->ContextObject, 'Context object not set when queue is 0');
163
164 # Looking it up by Queue => 1 works fine, and gets context object
165 $cf = RT::CustomField->new( RT->SystemUser );
166 $cf->LoadByName(Name => 'TestingCF', Queue => 1);
167 ok($cf->id, "Load does finds it, given a Name and Queue => 1" );
168 ok($cf->ContextObject->id, 'Context object is now set');
169
170 # Also find it with IncludeGlobal
171 $cf = RT::CustomField->new( RT->SystemUser );
172 $cf->LoadByName(Name => 'TestingCF', Queue => 1, IncludeGlobal => 1 );
173 ok($cf->id, "Load also finds it, given a Name and Queue => 1 and IncludeGlobal" );
174 ok($cf->ContextObject->id, 'Context object is also set');
175
176 # The explicit LookupType works
177 $cf = RT::CustomField->new( RT->SystemUser );
178 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType );
179 ok($cf->id, "Load also finds it, given a Name and LookupType" );
180 ok( ! $cf->ContextObject, 'But no context object gained');
181
182 # Explicit LookupType, ObjectId works
183 $cf = RT::CustomField->new( RT->SystemUser );
184 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType,
185                 ObjectId => 1 );
186 ok($cf->id, "Load still finds it, given a Name, LookupType, ObjectId" );
187 ok($cf->ContextObject->id, 'And gains a context obj');
188
189 # Explicit LookupType, ObjectId works
190 $cf = RT::CustomField->new( RT->SystemUser );
191 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType,
192                 ObjectId => 1, IncludeGlobal => 1 );
193 ok($cf->id, "Load also finds it, given a Name, LookupType, ObjectId, and IncludeGlobal" );
194 ok($cf->ContextObject->id, 'And gains a context obj');
195
196 # Look for a queue by name
197 $cf = RT::CustomField->new( RT->SystemUser );
198 $cf->LoadByName(Name => 'TestingCF', Queue => "General" );
199 ok($cf->id, "Finds it by queue name" );
200 ok($cf->ContextObject->id, 'But gains a context object');
201
202 # Look for a queue by name, include global
203 $cf = RT::CustomField->new( RT->SystemUser );
204 $cf->LoadByName(Name => 'TestingCF', Queue => "General", IncludeGlobal => 1 );
205 ok($cf->id, "By name, and queue name works with IncludeGlobal" );
206 ok($cf->ContextObject->id, 'And gains a context object');
207
208
209
210
211 # Change the lookup type to be a _queue_ CF
212 ($ok, $msg) = $cf->SetLookupType( RT::Queue->CustomFieldLookupType );
213 ok($ok, "Changed CF type to be a CF on queues" );
214 $ocf = RT::ObjectCustomField->new( RT->SystemUser );
215 ( $ok, $msg ) = $ocf->Add( CustomField => $cf->id, ObjectId => 0 );
216 ok($ok, "Applied globally" );
217
218 # Just looking by name gets you CFs of any type
219 $cf = RT::CustomField->new( RT->SystemUser );
220 $cf->LoadByName(Name => 'TestingCF');
221 ok($cf->id, "Find the CF by name, with no queue" );
222
223 # Queue => 0 means "ticket CF", so doesn't find it
224 $cf = RT::CustomField->new( RT->SystemUser );
225 $cf->LoadByName(Name => 'TestingCF', Queue => 0);
226 ok( ! $cf->id, "Wrong lookup type to find with Queue => 0" );
227
228 # Queue => 1 and IncludeGlobal also doesn't find it
229 $cf = RT::CustomField->new( RT->SystemUser );
230 $cf->LoadByName(Name => 'TestingCF', Queue => 0, IncludeGlobal => 1);
231 ok( ! $cf->id, "Also doesn't find with Queue => 0 and IncludeGlobal" );
232
233 # Find it with the right LookupType
234 $cf = RT::CustomField->new( RT->SystemUser );
235 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType );
236 ok($cf->id, "Found for the right lookup type" );
237
238 # Found globally
239 $cf = RT::CustomField->new( RT->SystemUser );
240 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType, ObjectId => 0 );
241 ok($cf->id, "Found for the right lookup type and ObjectId 0" );
242
243 # Also works with Queue instead of ObjectId
244 $cf = RT::CustomField->new( RT->SystemUser );
245 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType, Queue => 0 );
246 ok($cf->id, "Found for the right lookup type and Queue 0" );
247
248 # Not found without IncludeGlobal
249 $cf = RT::CustomField->new( RT->SystemUser );
250 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType, ObjectId => 1 );
251 ok( ! $cf->id, "Not found for ObjectId 1 and no IncludeGlobal" );
252
253 # Found with IncludeGlobal
254 $cf = RT::CustomField->new( RT->SystemUser );
255 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType,
256                 ObjectId => 1, IncludeGlobal => 1 );
257 ok($cf->id, "Found for ObjectId 1 and IncludeGlobal" );
258
259 # Found with IncludeGlobal and Queue instead of ObjectId
260 $cf = RT::CustomField->new( RT->SystemUser );
261 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType,
262                 ObjectId => 1, IncludeGlobal => 1 );
263 ok($cf->id, "Found for Queue 1 and IncludeGlobal" );
264
265
266
267 # Change the lookup type to be a _transaction_ CF
268 ($ok, $msg) = $cf->SetLookupType( RT::Transaction->CustomFieldLookupType );
269 ok($ok, "Changed CF type to be a CF on transactions" );
270 $ocf = RT::ObjectCustomField->new( RT->SystemUser );
271 ( $ok, $msg ) = $ocf->Add( CustomField => $cf->id, ObjectId => 0 );
272 ok($ok, "Applied globally" );
273
274 # Just looking by name gets you CFs of any type
275 $cf = RT::CustomField->new( RT->SystemUser );
276 $cf->LoadByName(Name => 'TestingCF');
277 ok($cf->id, "Find the CF by name, with no queue" );
278
279 # Queue => 0 means "ticket CF", so doesn't find it
280 $cf = RT::CustomField->new( RT->SystemUser );
281 $cf->LoadByName(Name => 'TestingCF', Queue => 0);
282 ok( ! $cf->id, "Wrong lookup type to find with Queue => 0" );
283
284 # Queue => 1 and IncludeGlobal also doesn't find it
285 $cf = RT::CustomField->new( RT->SystemUser );
286 $cf->LoadByName(Name => 'TestingCF', Queue => 0, IncludeGlobal => 1);
287 ok( ! $cf->id, "Also doesn't find with Queue => 0 and IncludeGlobal" );
288
289
290 # Change the lookup type to be a _user_ CF
291 $cf->Load(1);
292 ($ok, $msg) = $cf->SetLookupType( RT::User->CustomFieldLookupType );
293 ok($ok, "Changed CF type to be a CF on users" );
294 $ocf = RT::ObjectCustomField->new( RT->SystemUser );
295 ( $ok, $msg ) = $ocf->Add( CustomField => $cf->id, ObjectId => 0 );
296 ok($ok, "Applied globally" );
297
298 # Just looking by name gets you CFs of any type
299 $cf = RT::CustomField->new( RT->SystemUser );
300 $cf->LoadByName(Name => 'TestingCF');
301 ok($cf->id, "Find the CF by name, with no queue" );
302
303 # Queue => 0 means "ticket CF", so doesn't find it
304 $cf = RT::CustomField->new( RT->SystemUser );
305 $cf->LoadByName(Name => 'TestingCF', Queue => 0);
306 ok( ! $cf->id, "Wrong lookup type to find with Queue => 0" );
307
308 # Queue => 1 and IncludeGlobal also doesn't find it
309 $cf = RT::CustomField->new( RT->SystemUser );
310 $cf->LoadByName(Name => 'TestingCF', Queue => 0, IncludeGlobal => 1);
311 ok( ! $cf->id, "Also doesn't find with Queue => 0 and IncludeGlobal" );
312
313 # But RT::User->CustomFieldLookupType does
314 $cf = RT::CustomField->new( RT->SystemUser );
315 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::User->CustomFieldLookupType );
316 ok($cf->id, "User lookuptype does" );
317
318 # Also with an explicit global
319 $cf = RT::CustomField->new( RT->SystemUser );
320 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::User->CustomFieldLookupType, ObjectId => 0 );
321 ok($cf->id, "Also with user CF and explicit global" );
322
323
324
325 # Add a second, queue-specific CF to test load order
326 $cf->Load(1);
327 ($ok, $msg) = $cf->SetLookupType( RT::Ticket->CustomFieldLookupType );
328 ok($ok, "Changed CF type back to be a CF on tickets" );
329 $ocf = RT::ObjectCustomField->new( RT->SystemUser );
330 ( $ok, $msg ) = $ocf->Add( CustomField => $cf->id, ObjectId => 0 );
331 ok($ok, "Applied globally" );
332 ($ok, $msg) = $cf->SetDescription( "Global CF" );
333 ok($ok, "Changed CF type back to be a CF on tickets" );
334
335 ($ok, $msg) = $cf->Create(
336     Name        => 'TestingCF',
337     Queue       => '1',
338     Description => 'Queue-specific CF',
339     Type        => 'SelectSingle'
340 );
341 ok($ok, "Created second CF successfully");
342
343 # If passed just a name, you get the first by id
344 $cf = RT::CustomField->new( RT->SystemUser );
345 $cf->LoadByName(Name => 'TestingCF' );
346 like($cf->Description, qr/Global/, "Gets the first (global) one if just loading by name" );
347
348 # Ditto if also limited to lookuptype
349 $cf = RT::CustomField->new( RT->SystemUser );
350 $cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType );
351 like($cf->Description, qr/Global/, "Same, if one adds a LookupType" );
352
353 # Gets the global with Queue => 0
354 $cf = RT::CustomField->new( RT->SystemUser );
355 $cf->LoadByName(Name => 'TestingCF', Queue => 0 );
356 like($cf->Description, qr/Global/, "Specify Queue => 0 and get global" );
357
358 # Gets the queue with Queue => 1
359 $cf = RT::CustomField->new( RT->SystemUser );
360 $cf->LoadByName(Name => 'TestingCF', Queue => 1 );
361 like($cf->Description, qr/Queue/, "Specify Queue => 1 and get the queue" );
362
363 # Gets the queue with Queue => 1 and IncludeGlobal
364 $cf = RT::CustomField->new( RT->SystemUser );
365 $cf->LoadByName(Name => 'TestingCF', Queue => 1, IncludeGlobal => 1 );
366 like($cf->Description, qr/Queue/, "Specify Queue => 1 and IncludeGlobal and get the queue" );
367
368
369 # Disable one of them
370 ($ok, $msg) = $cf->SetDisabled(1);
371 ok($ok, "Disabled the Queue-specific one");
372
373 # With just a name, prefers the non-disabled
374 $cf = RT::CustomField->new( RT->SystemUser );
375 $cf->LoadByName(Name => 'TestingCF' );
376 like($cf->Description, qr/Global/, "Prefers non-disabled CFs" );
377
378 # Still finds the queue one, if asked
379 $cf = RT::CustomField->new( RT->SystemUser );
380 $cf->LoadByName(Name => 'TestingCF', Queue => 1 );
381 like($cf->Description, qr/Queue/, "Still loads the disabled queue CF" );
382
383 # Prefers the global one if IncludeGlobal
384 $cf = RT::CustomField->new( RT->SystemUser );
385 $cf->LoadByName(Name => 'TestingCF', Queue => 1, IncludeGlobal => 1 );
386 like($cf->Description, qr/Global/, "Prefers the global one with IncludeGlobal" );
387
388 # IncludeDisabled allows filtering out the disabled one
389 $cf = RT::CustomField->new( RT->SystemUser );
390 $cf->LoadByName(Name => 'TestingCF', Queue => 1, IncludeDisabled => 0 );
391 ok( ! $cf->id, "Doesn't find it if IncludeDisabled => 0" );
392
393
394 done_testing;