Commit | Line | Data |
---|---|---|
dc86f881 CW |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
7d61e75f | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
dc86f881 | 5 | | | |
7d61e75f TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
dc86f881 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
dc86f881 | 11 | |
dc86f881 | 12 | /** |
2158332a | 13 | * Tests for field options |
acb109b7 | 14 | * @group headless |
dc86f881 CW |
15 | */ |
16 | class CRM_Core_FieldOptionsTest extends CiviUnitTestCase { | |
33e61cb8 | 17 | |
4268623e CW |
18 | /** |
19 | * @var array | |
20 | */ | |
33e61cb8 CW |
21 | public $replaceOptions; |
22 | ||
4268623e CW |
23 | /** |
24 | * @var array | |
25 | */ | |
33e61cb8 CW |
26 | public $appendOptions; |
27 | ||
4268623e CW |
28 | /** |
29 | * @var string | |
30 | */ | |
33e61cb8 CW |
31 | public $targetField; |
32 | ||
00be9182 | 33 | public function setUp() { |
dc86f881 | 34 | parent::setUp(); |
9099cab3 | 35 | CRM_Utils_Hook::singleton()->setHook('civicrm_fieldOptions', [$this, 'hook_civicrm_fieldOptions']); |
dc86f881 CW |
36 | } |
37 | ||
2921fb78 CW |
38 | public function tearDown() { |
39 | parent::tearDown(); | |
9099cab3 | 40 | $this->quickCleanup(['civicrm_custom_field', 'civicrm_custom_group']); |
2921fb78 CW |
41 | } |
42 | ||
dc86f881 CW |
43 | /** |
44 | * Assure CRM_Core_PseudoConstant::get() is working properly for a range of | |
45 | * DAO fields having a <pseudoconstant> tag in the XML schema. | |
46 | */ | |
00be9182 | 47 | public function testOptionValues() { |
dc86f881 CW |
48 | /** |
49 | * baoName/field combinations to test | |
50 | * Format: array[BAO Name] = $properties, where properties is an array whose | |
51 | * named members can be: | |
52 | * - fieldName: the SQL column name within the DAO table. | |
53 | * - sample: Any one value which is expected in the list of option values. | |
54 | * - context: Context to pass | |
55 | * - props: Object properties to pass | |
56 | * - exclude: Any one value which should not be in the list. | |
57 | * - max: integer (default = 10) maximum number of option values expected. | |
58 | */ | |
9099cab3 CW |
59 | $fields = [ |
60 | 'CRM_Core_BAO_Address' => [ | |
61 | [ | |
dc86f881 CW |
62 | 'fieldName' => 'state_province_id', |
63 | 'sample' => 'California', | |
64 | 'max' => 60, | |
9099cab3 CW |
65 | 'props' => ['country_id' => 1228], |
66 | ], | |
67 | ], | |
68 | 'CRM_Contact_BAO_Contact' => [ | |
69 | [ | |
dc86f881 CW |
70 | 'fieldName' => 'contact_sub_type', |
71 | 'sample' => 'Team', | |
72 | 'exclude' => 'Organization', | |
9099cab3 CW |
73 | 'props' => ['contact_type' => 'Organization'], |
74 | ], | |
75 | ], | |
76 | ]; | |
dc86f881 CW |
77 | |
78 | foreach ($fields as $baoName => $baoFields) { | |
79 | foreach ($baoFields as $field) { | |
80 | $message = "BAO name: '{$baoName}', field: '{$field['fieldName']}'"; | |
81 | ||
9099cab3 | 82 | $props = CRM_Utils_Array::value('props', $field, []); |
262f0ecc | 83 | $optionValues = $baoName::buildOptions($field['fieldName'], 'create', $props); |
dc86f881 CW |
84 | $this->assertNotEmpty($optionValues, $message); |
85 | ||
86 | // Ensure sample value is contained in the returned optionValues. | |
87 | $this->assertContains($field['sample'], $optionValues, $message); | |
88 | ||
89 | // Exclude test | |
90 | if (!empty($field['exclude'])) { | |
91 | $this->assertNotContains($field['exclude'], $optionValues, $message); | |
92 | } | |
93 | ||
94 | // Ensure count of optionValues is not extraordinarily high. | |
95 | $max = CRM_Utils_Array::value('max', $field, 10); | |
96 | $this->assertLessThanOrEqual($max, count($optionValues), $message); | |
97 | } | |
98 | } | |
99 | } | |
96025800 | 100 | |
33e61cb8 CW |
101 | /** |
102 | * Ensure hook_civicrm_fieldOptions is working | |
103 | */ | |
104 | public function testHookFieldOptions() { | |
33e61cb8 CW |
105 | CRM_Core_PseudoConstant::flush(); |
106 | ||
107 | // Test replacing all options with a hook | |
108 | $this->targetField = 'case_type_id'; | |
9099cab3 CW |
109 | $this->replaceOptions = ['foo' => 'Foo', 'bar' => 'Bar']; |
110 | $result = $this->callAPISuccess('case', 'getoptions', ['field' => 'case_type_id']); | |
33e61cb8 CW |
111 | $this->assertEquals($result['values'], $this->replaceOptions); |
112 | ||
113 | // TargetField doesn't match - should get unmodified option list | |
114 | $originalGender = CRM_Contact_BAO_Contact::buildOptions('gender_id'); | |
115 | $this->assertNotEquals($originalGender, $this->replaceOptions); | |
116 | ||
117 | // This time we should get foo bar appended to the list | |
118 | $this->targetField = 'gender_id'; | |
9099cab3 | 119 | $this->appendOptions = ['foo' => 'Foo', 'bar' => 'Bar']; |
33e61cb8 CW |
120 | $this->replaceOptions = NULL; |
121 | CRM_Core_PseudoConstant::flush(); | |
122 | $result = CRM_Contact_BAO_Contact::buildOptions('gender_id'); | |
123 | $this->assertEquals($result, $originalGender + $this->appendOptions); | |
124 | } | |
125 | ||
2921fb78 CW |
126 | /** |
127 | * Ensure hook_civicrm_fieldOptions works with custom fields | |
128 | */ | |
129 | public function testHookFieldOptionsWithCustomFields() { | |
2921fb78 CW |
130 | // Create a custom field group for testing. |
131 | $custom_group_name = md5(microtime()); | |
9099cab3 | 132 | $api_params = [ |
2921fb78 CW |
133 | 'title' => $custom_group_name, |
134 | 'extends' => 'Individual', | |
135 | 'is_active' => TRUE, | |
9099cab3 | 136 | ]; |
2921fb78 CW |
137 | $customGroup = $this->callAPISuccess('customGroup', 'create', $api_params); |
138 | ||
139 | // Add a custom select field. | |
9099cab3 | 140 | $api_params = [ |
2921fb78 CW |
141 | 'custom_group_id' => $customGroup['id'], |
142 | 'label' => $custom_group_name . 1, | |
143 | 'html_type' => 'Select', | |
144 | 'data_type' => 'String', | |
9099cab3 | 145 | 'option_values' => [ |
2921fb78 CW |
146 | 'foo' => 'Foo', |
147 | 'bar' => 'Bar', | |
9099cab3 CW |
148 | ], |
149 | ]; | |
2921fb78 CW |
150 | $result = $this->callAPISuccess('custom_field', 'create', $api_params); |
151 | $customField1 = $result['id']; | |
152 | ||
153 | // Add a custom country field. | |
9099cab3 | 154 | $api_params = [ |
2921fb78 CW |
155 | 'custom_group_id' => $customGroup['id'], |
156 | 'label' => $custom_group_name . 2, | |
157 | 'html_type' => 'Select Country', | |
158 | 'data_type' => 'Country', | |
9099cab3 | 159 | ]; |
2921fb78 CW |
160 | $result = $this->callAPISuccess('custom_field', 'create', $api_params); |
161 | $customField2 = $result['id']; | |
162 | ||
163 | // Add a custom boolean field. | |
9099cab3 | 164 | $api_params = [ |
2921fb78 CW |
165 | 'custom_group_id' => $customGroup['id'], |
166 | 'label' => $custom_group_name . 3, | |
167 | 'html_type' => 'Radio', | |
168 | 'data_type' => 'Boolean', | |
9099cab3 | 169 | ]; |
2921fb78 CW |
170 | $result = $this->callAPISuccess('custom_field', 'create', $api_params); |
171 | $customField3 = $result['id']; | |
172 | ||
173 | $this->targetField = 'custom_' . $customField1; | |
174 | $this->replaceOptions = NULL; | |
9099cab3 | 175 | $this->appendOptions = ['baz' => 'Baz']; |
2921fb78 CW |
176 | $field = new CRM_Core_BAO_CustomField(); |
177 | $field->id = $customField1; | |
9099cab3 | 178 | $this->assertEquals(['foo' => 'Foo', 'bar' => 'Bar', 'baz' => 'Baz'], $field->getOptions()); |
2921fb78 CW |
179 | |
180 | $this->targetField = 'custom_' . $customField2; | |
9099cab3 | 181 | $this->replaceOptions = ['nowhere' => 'Nowhere']; |
2921fb78 CW |
182 | $field = new CRM_Core_BAO_CustomField(); |
183 | $field->id = $customField2; | |
184 | $this->assertEquals($this->replaceOptions + $this->appendOptions, $field->getOptions()); | |
185 | ||
186 | $this->targetField = 'custom_' . $customField3; | |
187 | $this->replaceOptions = NULL; | |
9099cab3 | 188 | $this->appendOptions = [2 => 'Maybe']; |
261b2d26 | 189 | $options = CRM_Core_PseudoConstant::get('CRM_Core_BAO_CustomField', $this->targetField); |
9099cab3 | 190 | $this->assertEquals([1 => 'Yes', 0 => 'No', 2 => 'Maybe'], $options); |
2921fb78 CW |
191 | } |
192 | ||
33e61cb8 | 193 | /** |
4268623e | 194 | * Implements hook_civicrm_fieldOptions(). |
33e61cb8 CW |
195 | */ |
196 | public function hook_civicrm_fieldOptions($entity, $field, &$options, $params) { | |
197 | if ($field == $this->targetField) { | |
198 | if (is_array($this->replaceOptions)) { | |
199 | $options = $this->replaceOptions; | |
200 | } | |
201 | if ($this->appendOptions) { | |
202 | $options += $this->appendOptions; | |
203 | } | |
204 | } | |
205 | } | |
206 | ||
dc86f881 | 207 | } |