Merge pull request #1458 from colemanw/contactTypeSearch
[civicrm-core.git] / tests / phpunit / WebTest / Case / CaseCustomFieldsTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.4 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License along with this program; if not, contact CiviCRM LLC |
21 | at info[AT]civicrm[DOT]org. If you have questions about the |
22 | GNU Affero General Public License or the licensing of CiviCRM, |
23 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
24 +--------------------------------------------------------------------+
25 */
26
27 require_once 'CiviTest/CiviSeleniumTestCase.php';
28 class WebTest_Case_CaseCustomFieldsTest extends CiviSeleniumTestCase {
29
30 protected function setUp() {
31 parent::setUp();
32 }
33
34 function testAddCase() {
35 $this->webtestLogin('admin');
36
37 // Enable CiviCase module if necessary
38 $this->enableComponents("CiviCase");
39
40 $customGrp1 = "CaseCustom_Data1_" . substr(sha1(rand()), 0, 7);
41
42 // create custom group1
43 $this->openCiviPage('admin/custom/group', 'reset=1');
44 $this->click("newCustomDataGroup");
45 $this->waitForPageToLoad($this->getTimeoutMsec());
46 $this->type("title", $customGrp1);
47 $this->select("extends[0]", "value=Case");
48 // Because it tends to cause problems, all uses of sleep() must be justified in comments
49 // Sleep should never be used for wait for anything to load from the server
50 // Justification for this instance: FIXME
51 sleep(1);
52 $this->select("extends_1", "value=2");
53 $this->click("_qf_Group_next-bottom");
54 $this->waitForPageToLoad($this->getTimeoutMsec());
55
56 // get custom group id
57 $customGrpId1 = $this->urlArg('gid');
58
59 $customId = $this->_testGetCustomFieldId($customGrpId1);
60 $cusId_1 = 'custom_' . $customId[0] . '_-1';
61 $cusId_2 = 'custom_' . $customId[1] . '_-1';
62 $cusId_3 = 'custom_' . $customId[2] . '_-1';
63
64 // let's give full CiviCase permissions.
65 $permission = array('edit-2-access-all-cases-and-activities', 'edit-2-access-my-cases-and-activities', 'edit-2-administer-civicase', 'edit-2-delete-in-civicase');
66 $this->changePermissions($permission);
67
68 // Log in as normal user
69 $this->webtestLogin();
70
71 // Go to reserved New Individual Profile to set value for logged in user's contact name (we'll need that later)
72 $this->openCiviPage('profile/edit', 'reset=1&gid=4', '_qf_Edit_next');
73 $testUserFirstName = "Testuserfirst";
74 $testUserLastName = "Testuserlast";
75 $this->type("first_name", $testUserFirstName);
76 $this->type("last_name", $testUserLastName);
77 $this->clickLink("_qf_Edit_next", "profilewrap4");
78
79 $this->openCiviPage('case/add', 'reset=1&action=add&atype=13&context=standalone', '_qf_Case_upload-bottom');
80
81 // Try submitting the form without creating or selecting a contact (test for CRM-7971)
82 $this->clickLink("_qf_Case_upload-bottom", "css=span.crm-error");
83
84 // Adding contact with randomized first name (so we can then select that contact when creating case)
85 // We're using pop-up New Contact dialog
86 $firstName = substr(sha1(rand()), 0, 7);
87 $lastName = "Fraser";
88 $contactName = "{$lastName}, {$firstName}";
89 $displayName = "{$firstName} {$lastName}";
90 $email = "{$lastName}.{$firstName}@example.org";
91 $custFname = "Mike" . substr(sha1(rand()), 0, 7);
92 $custMname = "Dav" . substr(sha1(rand()), 0, 7);
93 $custLname = "Krist" . substr(sha1(rand()), 0, 7);
94 $this->webtestNewDialogContact($firstName, $lastName, $email, $type = 4);
95
96 // Fill in other form values. We'll use a case type which is included in CiviCase sample data / xml files.
97 $caseTypeLabel = "Adult Day Care Referral";
98
99 // activity types we expect for this case type
100 $activityTypes = array("ADC referral", "Follow up", "Medical evaluation", "Mental health evaluation");
101 $caseRoles = array("Senior Services Coordinator", "Health Services Coordinator", "Benefits Specialist", "Client");
102 $caseStatusLabel = "Ongoing";
103 $subject = "Safe daytime setting - senior female";
104 $this->select("medium_id", "value=1");
105 $location = "Main offices";
106 $this->type("activity_location", $location);
107 $details = "65 year old female needs safe location during the day for herself and her dog. She is in good health but somewhat disoriented.";
108 $this->fillRichTextField("activity_details", $details, 'CKEditor');
109 $this->type("activity_subject", $subject);
110
111 $this->select("case_type_id", "label={$caseTypeLabel}");
112 // Because it tends to cause problems, all uses of sleep() must be justified in comments
113 // Sleep should never be used for wait for anything to load from the server
114 // Justification for this instance: FIXME
115 sleep(3);
116 $this->select("status_id", "label={$caseStatusLabel}");
117
118 // Choose Case Start Date.
119 // Using helper webtestFillDate function.
120 $this->webtestFillDate('start_date', 'now');
121 $today = date('F jS, Y', strtotime('now'));
122
123 $this->type("duration", "20");
124 $this->type("{$cusId_1}", $custFname);
125 $this->type("{$cusId_2}", $custMname);
126 $this->type("{$cusId_3}", $custLname);
127 $this->clickLink("_qf_Case_upload-bottom", "_qf_CaseView_cancel-bottom");
128
129 // Is status message correct?
130 $this->assertTextPresent("Case opened successfully.", "Save successful status message didn't show up after saving!");
131 $this->click("_qf_CaseView_cancel-bottom");
132 $this->waitForPageToLoad($this->getTimeoutMsec());
133 $this->openCiviPage('case', 'reset=1', "xpath=//table[@class='caseSelector']/tbody//tr/td[2]/a[text()='{$contactName}']/../../td[8]/a[text()='Open Case']");
134 $this->click("xpath=//table[@class='caseSelector']/tbody//tr/td[2]/a[text()='{$contactName}']/../../td[8]/a[text()='Open Case']");
135 $this->waitForElementPresent("xpath=//div[@class='ui-dialog-buttonset']/button/span[text()='Done']");
136 // Because it tends to cause problems, all uses of sleep() must be justified in comments
137 // Sleep should never be used for wait for anything to load from the server
138 // Justification for this instance: FIXME
139 sleep(3);
140
141 $openCaseData = array(
142 "Client" => $displayName,
143 "Activity Type" => "Open Case",
144 "Subject" => $subject,
145 "Created By" => "{$testUserFirstName} {$testUserLastName}",
146 "Reported By" => "{$testUserFirstName} {$testUserLastName}",
147 "Medium" => "In Person",
148 "Location" => $location,
149 "Date and Time" => $today,
150 "Status" => "Completed",
151 "Priority" => "Normal",
152 );
153 $this->webtestVerifyTabularData($openCaseData);
154 $this->click("xpath=//div[@class='ui-dialog-buttonset']/button/span[text()='Done']");
155
156 // verify if custom data is present
157 $this->openCiviPage('case', 'reset=1');
158 $this->click("xpath=//table[@class='caseSelector']/tbody//tr/td[2]/a[text()='{$contactName}']/../../td[9]/span/a[text()='Manage']");
159 $this->waitForPageToLoad($this->getTimeoutMsec());
160 $this->click("css=#{$customGrp1} .crm-accordion-header");
161 $this->waitForElementPresent("css=#{$customGrp1} a.button");
162 $cusId_1 = 'custom_' . $customId[0] . '_1';
163 $cusId_2 = 'custom_' . $customId[1] . '_1';
164 $cusId_3 = 'custom_' . $customId[2] . '_1';
165 $this->click("css=#{$customGrp1} a.button");
166 // Because it tends to cause problems, all uses of sleep() must be justified in comments
167 // Sleep should never be used for wait for anything to load from the server
168 // Justification for this instance: FIXME
169 sleep(2);
170 $this->waitForElementPresent("{$cusId_1}");
171 $custFname = "Miky" . substr(sha1(rand()), 0, 7);
172 $custMname = "Davy" . substr(sha1(rand()), 0, 7);
173 $custLname = "Kristy" . substr(sha1(rand()), 0, 7);
174 $this->type("{$cusId_1}", $custFname);
175 $this->type("{$cusId_2}", $custMname);
176 $this->type("{$cusId_3}", $custLname);
177 $this->click("_qf_CustomData_upload");
178 // Because it tends to cause problems, all uses of sleep() must be justified in comments
179 // Sleep should never be used for wait for anything to load from the server
180 // Justification for this instance: FIXME
181 sleep(2);
182 $this->openCiviPage('case', 'reset=1');
183 $this->click("xpath=//table[@class='caseSelector']/tbody//tr/td[2]/a[text()='{$contactName}']/../../td[8]/a[text()='Change Custom Data']");
184 // Because it tends to cause problems, all uses of sleep() must be justified in comments
185 // Sleep should never be used for wait for anything to load from the server
186 // Justification for this instance: FIXME
187 sleep(3);
188 $openCaseChangeData = array(
189 "Client" => $displayName,
190 "Activity Type" => "Change Custom Data",
191 "Subject" => $customGrp1 . " : change data",
192 "Created By" => "{$testUserFirstName} {$testUserLastName}",
193 "Reported By" => "{$testUserFirstName} {$testUserLastName}",
194 "Date and Time" => $today,
195 "Status" => "Completed",
196 "Priority" => "Normal",
197 );
198 $this->webtestVerifyTabularData($openCaseChangeData);
199 $this->click("xpath=//div[@class='ui-dialog-buttonset']/button/span[text()='Done']");
200 // Because it tends to cause problems, all uses of sleep() must be justified in comments
201 // Sleep should never be used for wait for anything to load from the server
202 // Justification for this instance: FIXME
203 sleep(2);
204 $this->_testAdvansearchCaseData($customId, $custFname, $custMname, $custLname);
205 $this->_testDeleteCustomData($customGrpId1, $customId);
206 }
207
208 function _testVerifyCaseSummary($validateStrings, $activityTypes) {
209 $this->assertStringsPresent($validateStrings);
210 foreach ($activityTypes as $aType) {
211 $this->assertText("activity_type_id", $aType);
212 }
213 $this->assertElementPresent("link=Assign to Another Client", "Assign to Another Client link is missing.");
214 $this->assertElementPresent("name=case_report_all", "Print Case Summary button is missing.");
215 }
216
217 function _testGetCustomFieldId($customGrpId1, $noteRichEditor=FALSE) {
218 $customId = array();
219
220 if ($noteRichEditor) {
221 // Create a custom data to add in profile
222 $field1 = "Note_Textarea" . substr(sha1(rand()), 0, 7);
223 $field2 = "Note_Richtexteditor" . substr(sha1(rand()), 0, 7);
224
225 // add custom fields for group 1
226 $this->openCiviPage('admin/custom/group/field/add', array('reset' => 1, 'action' => 'add', 'gid' => $customGrpId1));
227 $this->type("label", $field1);
228 $this->select("data_type_0", "value=4");
229 $this->select("data_type_1", "value=TextArea");
230 $this->check("is_searchable");
231 $this->clickLink("_qf_Field_next_new-bottom");
232
233 $this->type("label", $field2);
234 $this->select("data_type_0", "value=4");
235 //$this->select("data_type_1", "value=TextArea");
236 $this->select("data_type_1", "value=RichTextEditor");
237 $this->check("is_searchable");
238 $this->clickLink("_qf_Field_next_new-bottom");
239
240 // get id of custom fields
241 $this->openCiviPage("admin/custom/group/field", array('reset' => 1, 'action' => 'browse', 'gid' => $customGrpId1));
242 $custom1 = explode('&id=', $this->getAttribute("xpath=//div[@id='field_page']//table/tbody//tr[1]/td[8]/span/a[text()='Edit Field']/@href"));
243 $custom1 = $custom1[1];
244 array_push($customId, $custom1);
245 $custom2 = explode('&id=', $this->getAttribute("xpath=//div[@id='field_page']//table/tbody//tr[2]/td[8]/span/a[text()='Edit Field']/@href"));
246 $custom2 = $custom2[1];
247 array_push($customId, $custom2);
248 }
249 else {
250 // Create a custom data to add in profile
251 $field1 = "Fname" . substr(sha1(rand()), 0, 7);
252 $field2 = "Mname" . substr(sha1(rand()), 0, 7);
253 $field3 = "Lname" . substr(sha1(rand()), 0, 7);
254
255 // add custom fields for group 1
256 $this->openCiviPage('admin/custom/group/field/add', array('reset' => 1, 'action' => 'add', 'gid' => $customGrpId1));
257 $this->type("label", $field1);
258 $this->check("is_searchable");
259 $this->click("_qf_Field_next_new-bottom");
260 $this->waitForPageToLoad($this->getTimeoutMsec());
261
262 $this->type("label", $field2);
263 $this->check("is_searchable");
264 $this->click("_qf_Field_next_new-bottom");
265 $this->waitForPageToLoad($this->getTimeoutMsec());
266
267 $this->type("label", $field3);
268 $this->check("is_searchable");
269 $this->click("_qf_Field_next-bottom");
270 $this->waitForPageToLoad($this->getTimeoutMsec());
271
272 // get id of custom fields
273 $this->openCiviPage("admin/custom/group/field", array('reset' => 1, 'action' => 'browse', 'gid' => $customGrpId1));
274 $custom1 = explode('&id=', $this->getAttribute("xpath=//div[@id='field_page']//table/tbody//tr[1]/td[8]/span/a[text()='Edit Field']/@href"));
275 $custom1 = $custom1[1];
276 array_push($customId, $custom1);
277 $custom2 = explode('&id=', $this->getAttribute("xpath=//div[@id='field_page']//table/tbody//tr[2]/td[8]/span/a[text()='Edit Field']/@href"));
278 $custom2 = $custom2[1];
279 array_push($customId, $custom2);
280 $custom3 = explode('&id=', $this->getAttribute("xpath=//div[@id='field_page']//table/tbody//tr[3]/td[8]/span/a[text()='Edit Field']/@href"));
281 $custom3 = $custom3[1];
282 array_push($customId, $custom3);
283 }
284
285 return $customId;
286 }
287
288 function _testDeleteCustomData($customGrpId1, $customId) {
289 // delete all custom data
290 foreach ($customId as $cKey => $cValue) {
291 $this->openCiviPage("admin/custom/group/field", array('action' => 'delete', 'reset' => '1', 'gid' => $customGrpId1, 'id' => $cValue));
292 $this->clickLink("_qf_DeleteField_next-bottom");
293 }
294
295 // delete custom group
296 $this->openCiviPage("admin/custom/group", "action=delete&reset=1&id=" . $customGrpId1);
297 $this->clickLink("_qf_DeleteGroup_next-bottom");
298 }
299
300 /**
301 * CRM-12812
302 */
303 function testCaseCustomNoteRichEditor() {
304 $this->webtestLogin('admin');
305
306 //setting ckeditor as WYSIWYG
307 $this->openCiviPage('admin/setting/preferences/display', 'reset=1', '_qf_Display_next-bottom');
308 $this->select('editor_id', 'CKEditor');
309 $this->clickLink('_qf_Display_next-bottom');
310
311 // Enable CiviCase module if necessary
312 $this->enableComponents("CiviCase");
313
314 $customGrp1 = "CaseCustom_Data1_" . substr(sha1(rand()), 0, 7);
315
316 // create custom group1
317 $this->openCiviPage('admin/custom/group', 'reset=1');
318 $this->clickLink("newCustomDataGroup");
319 $this->type("title", $customGrp1);
320 $this->select("extends[0]", "value=Case");
321 $this->select("extends_1", "value=2");
322 $this->clickLink("_qf_Group_next-bottom");
323
324 // get custom group id
325 $customGrpId1 = $this->urlArg('gid');
326
327 $customId = $this->_testGetCustomFieldId($customGrpId1, TRUE);
328 $cusId_1 = 'custom_' . $customId[0] . '_-1';
329 $cusId_2 = 'custom_' . $customId[1] . '_-1';
330
331 // let's give full CiviCase permissions.
332 $permission = array('edit-2-access-all-cases-and-activities', 'edit-2-access-my-cases-and-activities', 'edit-2-administer-civicase', 'edit-2-delete-in-civicase');
333 $this->changePermissions($permission);
334
335 // Log in as normal user
336 $this->webtestLogin();
337
338 // Go to reserved New Individual Profile to set value for logged in user's contact name (we'll need that later)
339 $this->openCiviPage('profile/edit', 'reset=1&gid=4', '_qf_Edit_next');
340 $testUserFirstName = "Testuserfirst";
341 $testUserLastName = "Testuserlast";
342 $this->type("first_name", $testUserFirstName);
343 $this->type("last_name", $testUserLastName);
344 $this->clickLink("_qf_Edit_next", "profilewrap4");
345
346 $this->openCiviPage('case/add', 'reset=1&action=add&atype=13&context=standalone', '_qf_Case_upload-bottom');
347
348 // Try submitting the form without creating or selecting a contact (test for CRM-7971)
349 $this->clickLink("_qf_Case_upload-bottom", "css=span.crm-error");
350
351 // Adding contact with randomized first name (so we can then select that contact when creating case)
352 // We're using pop-up New Contact dialog
353 $firstName = substr(sha1(rand()), 0, 7);
354 $lastName = "Fraser";
355 $contactName = "{$lastName}, {$firstName}";
356 $displayName = "{$firstName} {$lastName}";
357 $email = "{$lastName}.{$firstName}@example.org";
358 $custFname = "Mike" . substr(sha1(rand()), 0, 7);
359 $custLname = "Krist" . substr(sha1(rand()), 0, 7);
360 $this->webtestNewDialogContact($firstName, $lastName, $email, $type = 4);
361
362 // Fill in other form values. We'll use a case type which is included in CiviCase sample data / xml files.
363 $caseTypeLabel = "Adult Day Care Referral";
364
365 // activity types we expect for this case type
366 $activityTypes = array("ADC referral", "Follow up", "Medical evaluation", "Mental health evaluation");
367 $caseRoles = array("Senior Services Coordinator", "Health Services Coordinator", "Benefits Specialist", "Client");
368 $caseStatusLabel = "Ongoing";
369 $subject = "Safe daytime setting - senior female";
370 $this->select("medium_id", "value=1");
371 $location = "Main offices";
372 $this->type("activity_location", $location);
373 $details = "65 year old female needs safe location during the day for herself and her dog. She is in good health but somewhat disoriented.";
374 $this->fillRichTextField("activity_details", $details, 'CKEditor');
375 $this->type("activity_subject", $subject);
376
377 $this->select("case_type_id", "label={$caseTypeLabel}");
378 $this->select("status_id", "label={$caseStatusLabel}");
379
380 // Choose Case Start Date.
381 // Using helper webtestFillDate function.
382 $this->webtestFillDate('start_date', 'now');
383 $today = date('F jS, Y', strtotime('now'));
384
385 $this->type("duration", "20");
386 $this->type("{$cusId_1}", $custFname);
387 $this->type("{$cusId_2}", $custLname);
388 $this->clickLink("_qf_Case_upload-bottom", "_qf_CaseView_cancel-bottom");
389
390 // Is status message correct?
391 $this->assertTextPresent("Case opened successfully.", "Save successful status message didn't show up after saving!");
392 $this->clickLink("_qf_CaseView_cancel-bottom");
393
394 $this->openCiviPage('case', 'reset=1');
395 $this->waitForElementPresent("xpath=//table[@class='caseSelector']/tbody//tr/td[2]/a[text()='{$contactName}']/../../td[8]/a[text()='Open Case']");
396
397 $this->click("xpath=//table[@class='caseSelector']/tbody//tr/td[2]/a[text()='{$contactName}']/../../td[8]/a[text()='Open Case']");
398 $this->waitForElementPresent("xpath=//div[@class='ui-dialog-buttonset']/button/span[text()='Done']");
399
400 $openCaseData = array(
401 "Client" => $displayName,
402 "Activity Type" => "Open Case",
403 "Subject" => $subject,
404 "Created By" => "{$testUserFirstName} {$testUserLastName}",
405 "Reported By" => "{$testUserFirstName} {$testUserLastName}",
406 "Medium" => "In Person",
407 "Location" => $location,
408 "Date and Time" => $today,
409 "Status" => "Completed",
410 "Priority" => "Normal",
411 );
412 // wait for elements to load
413 foreach ($openCaseData as $label => $value) {
414 $this->waitForElementPresent("xpath=//table/tbody/tr/td[text()='{$label}']/following-sibling::td");
415 }
416 $this->webtestVerifyTabularData($openCaseData);
417 $this->click("xpath=//div[@class='ui-dialog-buttonset']/button/span[text()='Done']");
418
419 // verify if custom data is present
420 $this->openCiviPage('case', 'reset=1');
421 $this->clickLink("xpath=//table[@class='caseSelector']/tbody//tr/td[2]/a[text()='{$contactName}']/../../td[9]/span/a[text()='Manage']", "css=#{$customGrp1} .crm-accordion-header");
422
423 $this->click("css=#{$customGrp1} .crm-accordion-header");
424
425 $cusId_1 = 'custom_' . $customId[0] . '_1';
426 $cusId_2 = 'custom_' . $customId[1] . '_1';
427 $this->click("css=#{$customGrp1} a.button");
428
429 // wait for dialog element
430 $this->waitForElementPresent("css=div.ui-dialog div.ui-dialog-titlebar");
431 // check for dialog box Title
432 $this->assertElementContainsText("css=div.ui-dialog div.ui-dialog-titlebar", 'Update Case Information');
433
434 $custFname = "Miky" . substr(sha1(rand()), 0, 7);
435 $custLname = "Kristy" . substr(sha1(rand()), 0, 7);
436 $this->type("{$cusId_1}", $custFname);
437
438 // Wait for rich text editor element
439 $this->waitForElementPresent("css=div#cke_{$cusId_2}");
440
441 $this->fillRichTextField("{$cusId_2}", $custLname, 'CKEditor');
442 $this->click("_qf_CustomData_upload");
443 // delete custom data
444 $this->_testDeleteCustomData($customGrpId1, $customId);
445 }
446
447 function _testAdvansearchCaseData($customId, $custFname, $custMname, $custLname) {
448 // search casecontact
449 $this->openCiviPage('contact/search/advanced', 'reset=1', '_qf_Advanced_refresh');
450 $this->click("CiviCase");
451 $this->waitForElementPresent('case_from_relative');
452 $cusId_1 = 'custom_' . $customId[0];
453 $cusId_2 = 'custom_' . $customId[1];
454 $cusId_3 = 'custom_' . $customId[2];
455 $this->type("{$cusId_1}", $custFname);
456 $this->type("{$cusId_2}", $custMname);
457 $this->type("{$cusId_3}", $custLname);
458 $this->click("_qf_Advanced_refresh");
459 $this->waitForPageToLoad($this->getTimeoutMsec());
460 $this->assertElementContainsText('crm-container', '1 Contact');
461 }
462 }
463