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