Merge pull request #22886 from demeritcowboy/contributionview-notice3
[civicrm-core.git] / tests / phpunit / api / v4 / Action / CustomValueTest.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
6 | |
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
10 +--------------------------------------------------------------------+
11 */
12
13 /**
14 *
15 * @package CRM
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 */
18
19
20 namespace api\v4\Action;
21
22 use Civi\Api4\CustomField;
23 use Civi\Api4\CustomGroup;
24 use Civi\Api4\CustomValue;
25 use Civi\Api4\Contact;
26 use Civi\Api4\Entity;
27
28 /**
29 * @group headless
30 */
31 class CustomValueTest extends BaseCustomValueTest {
32
33 protected $contactID;
34
35 /**
36 * Test CustomValue::GetFields/Get/Create/Update/Replace/Delete
37 */
38 public function testCRUD() {
39 $optionValues = ['r' => 'Red', 'g' => 'Green', 'b' => 'Blue'];
40
41 $group = uniqid('groupc');
42 $colorFieldName = uniqid('colorc');
43 $multiFieldName = uniqid('chkbx');
44 $textFieldName = uniqid('txt');
45
46 $customGroup = CustomGroup::create(FALSE)
47 ->addValue('title', $group)
48 ->addValue('extends', 'Contact')
49 ->addValue('is_multiple', TRUE)
50 ->execute()
51 ->first();
52
53 $colorField = CustomField::create(FALSE)
54 ->addValue('label', $colorFieldName)
55 ->addValue('option_values', $optionValues)
56 ->addValue('custom_group_id', $customGroup['id'])
57 ->addValue('html_type', 'Select')
58 ->addValue('data_type', 'String')
59 ->execute()->first();
60
61 $multiField = CustomField::create(FALSE)
62 ->addValue('label', $multiFieldName)
63 ->addValue('option_values', $optionValues)
64 ->addValue('custom_group_id', $customGroup['id'])
65 ->addValue('html_type', 'CheckBox')
66 ->addValue('data_type', 'String')
67 ->execute()->first();
68
69 $textField = CustomField::create(FALSE)
70 ->addValue('label', $textFieldName)
71 ->addValue('custom_group_id', $customGroup['id'])
72 ->addValue('html_type', 'Text')
73 ->addValue('data_type', 'String')
74 ->execute()->first();
75
76 $this->contactID = Contact::create(FALSE)
77 ->addValue('first_name', 'Johann')
78 ->addValue('last_name', 'Tester')
79 ->addValue('contact_type', 'Individual')
80 ->execute()
81 ->first()['id'];
82
83 // Ensure virtual api entity has been created
84 $entity = Entity::get(FALSE)
85 ->addWhere('name', '=', "Custom_$group")
86 ->execute()->single();
87 $this->assertEquals(['CustomValue'], $entity['type']);
88 $this->assertEquals(['id'], $entity['primary_key']);
89 $this->assertEquals($customGroup['table_name'], $entity['table_name']);
90 $this->assertEquals('Civi\Api4\CustomValue', $entity['class']);
91 $this->assertEquals([$group], $entity['class_args']);
92 $this->assertEquals('secondary', $entity['searchable']);
93
94 // Retrieve and check the fields of CustomValue = Custom_$group
95 $fields = CustomValue::getFields($group)->setLoadOptions(TRUE)->setCheckPermissions(FALSE)->execute();
96 $expectedResult = [
97 [
98 'custom_group' => $group,
99 'type' => 'Field',
100 'name' => $colorFieldName,
101 'title' => $colorFieldName,
102 'entity' => "Custom_$group",
103 'table_name' => $customGroup['table_name'],
104 'column_name' => $colorField['column_name'],
105 'data_type' => 'String',
106 'fk_entity' => NULL,
107 'serialize' => 0,
108 'options' => $optionValues,
109 ],
110 [
111 'custom_group' => $group,
112 'type' => 'Field',
113 'name' => $multiFieldName,
114 'title' => $multiFieldName,
115 'entity' => "Custom_$group",
116 'table_name' => $customGroup['table_name'],
117 'column_name' => $multiField['column_name'],
118 'data_type' => 'String',
119 'fk_entity' => NULL,
120 'serialize' => 1,
121 'options' => $optionValues,
122 ],
123 [
124 'custom_group' => $group,
125 'type' => 'Field',
126 'name' => $textFieldName,
127 'title' => $textFieldName,
128 'entity' => "Custom_$group",
129 'table_name' => $customGroup['table_name'],
130 'column_name' => $textField['column_name'],
131 'data_type' => 'String',
132 'fk_entity' => NULL,
133 'serialize' => 0,
134 ],
135 [
136 'name' => 'id',
137 'type' => 'Field',
138 'title' => ts('Custom Value ID'),
139 'entity' => "Custom_$group",
140 'table_name' => $customGroup['table_name'],
141 'column_name' => 'id',
142 'data_type' => 'Integer',
143 'fk_entity' => NULL,
144 ],
145 [
146 'name' => 'entity_id',
147 'type' => 'Field',
148 'title' => ts('Entity ID'),
149 'table_name' => $customGroup['table_name'],
150 'column_name' => 'entity_id',
151 'entity' => "Custom_$group",
152 'data_type' => 'Integer',
153 'fk_entity' => 'Contact',
154 ],
155 ];
156
157 foreach ($expectedResult as $key => $field) {
158 foreach ($field as $attr => $value) {
159 $this->assertEquals($expectedResult[$key][$attr], $fields[$key][$attr], "$key $attr");
160 }
161 }
162
163 // CASE 1: Test CustomValue::create
164 // Create two records for a single contact and using CustomValue::get ensure that two records are created
165 $created = [
166 CustomValue::create($group)
167 ->addValue($colorFieldName, 'g')
168 ->addValue("entity_id", $this->contactID)
169 ->execute()->first(),
170 CustomValue::create($group)
171 ->addValue($colorFieldName . ':label', 'Red')
172 ->addValue("entity_id", $this->contactID)
173 ->execute()->first(),
174 ];
175 // fetch custom values using API4 CustomValue::get
176 $result = CustomValue::get($group)
177 ->addSelect('id', 'entity_id', $colorFieldName, $colorFieldName . ':label')
178 ->addOrderBy($colorFieldName, 'ASC')
179 ->execute();
180
181 // check if two custom values are created
182 $this->assertEquals(2, count($result));
183 $expectedResult = [
184 [
185 'id' => 1,
186 $colorFieldName => 'g',
187 $colorFieldName . ':label' => 'Green',
188 'entity_id' => $this->contactID,
189 ],
190 [
191 'id' => 2,
192 $colorFieldName => 'r',
193 $colorFieldName . ':label' => 'Red',
194 'entity_id' => $this->contactID,
195 ],
196 ];
197 // match the data
198 foreach ($expectedResult as $key => $field) {
199 foreach ($field as $attr => $value) {
200 $this->assertEquals($expectedResult[$key][$attr], $result[$key][$attr]);
201 if (!strpos($attr, ':')) {
202 $this->assertEquals($expectedResult[$key][$attr], $created[$key][$attr]);
203 }
204 }
205 }
206
207 // CASE 2: Test CustomValue::update
208 // Update a records whose id is 1 and change the custom field (name = Color) value to 'Blue' from 'Green'
209 CustomValue::update($group)
210 ->addWhere("id", "=", 1)
211 ->addValue($colorFieldName . ':label', 'Blue')
212 ->execute();
213
214 // ensure that the value is changed for id = 1
215 $color = CustomValue::get($group)
216 ->addWhere("id", "=", 1)
217 ->execute()
218 ->first()[$colorFieldName];
219 $this->assertEquals('b', $color);
220
221 // CASE 3: Test CustomValue::replace
222 // create a second contact which will be used to replace the custom values, created earlier
223 $secondContactID = Contact::create(FALSE)
224 ->addValue('first_name', 'Adam')
225 ->addValue('last_name', 'Tester')
226 ->addValue('contact_type', 'Individual')
227 ->execute()
228 ->first()['id'];
229 // Replace all the records which was created earlier with entity_id = first contact
230 // with custom record [$colorField => 'g', 'entity_id' => $secondContactID]
231 CustomValue::replace($group)
232 ->setRecords([[$colorFieldName => 'g', $multiFieldName . ':label' => ['Red', 'Green'], 'entity_id' => $secondContactID]])
233 ->addWhere('entity_id', '=', $this->contactID)
234 ->execute();
235
236 // Check the two records created earlier is replaced by new contact
237 $result = CustomValue::get($group)
238 ->addSelect('id', 'entity_id', $colorFieldName, $colorFieldName . ':label', $multiFieldName, $multiFieldName . ':label')
239 ->execute();
240 $this->assertEquals(1, count($result));
241
242 $expectedResult = [
243 [
244 'id' => 3,
245 $colorFieldName => 'g',
246 $colorFieldName . ':label' => 'Green',
247 $multiFieldName => ['r', 'g'],
248 $multiFieldName . ':label' => ['Red', 'Green'],
249 'entity_id' => $secondContactID,
250 ],
251 ];
252 foreach ($expectedResult as $key => $field) {
253 foreach ($field as $attr => $value) {
254 $this->assertEquals($expectedResult[$key][$attr], $result[$key][$attr]);
255 }
256 }
257
258 // CASE 4: Test CustomValue::delete
259 // There is only record left whose id = 3, delete that record on basis of criteria id = 3
260 CustomValue::delete($group)->addWhere("id", "=", 3)->execute();
261 $result = CustomValue::get($group)->execute();
262 // check that there are no custom values present
263 $this->assertEquals(0, count($result));
264 }
265
266 /**
267 * Whenever a CustomGroup toggles the `is_multiple` flag, the entity-list should be updated.
268 *
269 * @throws \API_Exception
270 * @throws \Civi\API\Exception\UnauthorizedException
271 */
272 public function testEntityRefresh() {
273 $groupName = uniqid('groupc');
274
275 $this->assertNotContains("Custom_$groupName", Entity::get()->execute()->column('name'));
276
277 CustomGroup::create(FALSE)
278 ->addValue('title', $groupName)
279 ->addValue('extends', 'Contact')
280 ->addValue('is_multiple', FALSE)
281 ->execute();
282
283 $this->assertNotContains("Custom_$groupName", Entity::get()->execute()->column('name'));
284
285 CustomGroup::update(FALSE)
286 ->addWhere('name', '=', $groupName)
287 ->addValue('is_multiple', TRUE)
288 ->execute();
289 $this->assertContains("Custom_$groupName", Entity::get()->execute()->column('name'));
290
291 CustomGroup::update(FALSE)
292 ->addWhere('name', '=', $groupName)
293 ->addValue('is_multiple', FALSE)
294 ->execute();
295 $this->assertNotContains("Custom_$groupName", Entity::get()->execute()->column('name'));
296 }
297
298 }