Merge pull request #17842 from seamuslee001/regen
[civicrm-core.git] / tests / phpunit / api / v4 / Entity / ConformanceTest.php
CommitLineData
19b53e5b
C
1<?php
2
380f3545
TO
3/*
4 +--------------------------------------------------------------------+
7d61e75f 5 | Copyright CiviCRM LLC. All rights reserved. |
380f3545 6 | |
7d61e75f
TO
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 |
380f3545
TO
10 +--------------------------------------------------------------------+
11 */
12
13/**
14 *
15 * @package CRM
ca5cec67 16 * @copyright CiviCRM LLC https://civicrm.org/licensing
380f3545
TO
17 */
18
19
19b53e5b
C
20namespace api\v4\Entity;
21
22use Civi\Api4\Entity;
23use api\v4\Traits\TableDropperTrait;
24use api\v4\UnitTestCase;
25
26/**
27 * @group headless
28 */
29class ConformanceTest extends UnitTestCase {
30
31 use TableDropperTrait;
32 use \api\v4\Traits\OptionCleanupTrait {
33 setUp as setUpOptionCleanup;
34 }
35
36 /**
37 * @var \api\v4\Service\TestCreationParameterProvider
38 */
39 protected $creationParamProvider;
40
41 /**
42 * Set up baseline for testing
43 */
44 public function setUp() {
45 $tablesToTruncate = [
46 'civicrm_custom_group',
47 'civicrm_custom_field',
48 'civicrm_group',
49 'civicrm_event',
50 'civicrm_participant',
51 ];
52 $this->dropByPrefix('civicrm_value_myfavorite');
53 $this->cleanup(['tablesToTruncate' => $tablesToTruncate]);
54 $this->setUpOptionCleanup();
55 $this->loadDataSet('ConformanceTest');
56 $this->creationParamProvider = \Civi::container()->get('test.param_provider');
57 parent::setUp();
19b53e5b
C
58 }
59
5acc6183 60 /**
61 * Get entities to test.
62 *
63 * @return array
64 *
65 * @throws \API_Exception
66 * @throws \Civi\API\Exception\UnauthorizedException
67 */
19b53e5b
C
68 public function getEntities() {
69 return Entity::get()->setCheckPermissions(FALSE)->execute()->column('name');
70 }
71
72 /**
73 * Fixme: This should use getEntities as a dataProvider but that fails for some reason
74 */
75 public function testConformance() {
76 $entities = $this->getEntities();
77 $this->assertNotEmpty($entities);
78
79 foreach ($entities as $data) {
80 $entity = $data;
81 $entityClass = 'Civi\Api4\\' . $entity;
82
83 $actions = $this->checkActions($entityClass);
84
85 // Go no further if it's not a CRUD entity
86 if (array_diff(['get', 'create', 'update', 'delete'], array_keys($actions))) {
87 continue;
88 }
89
90 $this->checkFields($entityClass, $entity);
91 $id = $this->checkCreation($entity, $entityClass);
92 $this->checkGet($entityClass, $id, $entity);
93 $this->checkGetCount($entityClass, $id, $entity);
94 $this->checkUpdateFailsFromCreate($entityClass, $id);
95 $this->checkWrongParamType($entityClass);
96 $this->checkDeleteWithNoId($entityClass);
97 $this->checkDeletion($entityClass, $id);
98 $this->checkPostDelete($entityClass, $id, $entity);
99 }
100 }
101
102 /**
103 * @param string $entityClass
5acc6183 104 * @param string $entity
19b53e5b
C
105 */
106 protected function checkFields($entityClass, $entity) {
107 $fields = $entityClass::getFields()
108 ->setCheckPermissions(FALSE)
109 ->setIncludeCustom(FALSE)
110 ->execute()
111 ->indexBy('name');
112
113 $errMsg = sprintf('%s is missing required ID field', $entity);
114 $subset = ['data_type' => 'Integer'];
115
116 $this->assertArraySubset($subset, $fields['id'], $errMsg);
117 }
118
119 /**
120 * @param string $entityClass
5acc6183 121 *
122 * @return array
19b53e5b
C
123 */
124 protected function checkActions($entityClass) {
125 $actions = $entityClass::getActions()
126 ->setCheckPermissions(FALSE)
127 ->execute()
128 ->indexBy('name');
129
130 $this->assertNotEmpty($actions);
131 return (array) $actions;
132 }
133
134 /**
135 * @param string $entity
136 * @param \Civi\Api4\Generic\AbstractEntity|string $entityClass
137 *
138 * @return mixed
139 */
140 protected function checkCreation($entity, $entityClass) {
141 $requiredParams = $this->creationParamProvider->getRequired($entity);
142 $createResult = $entityClass::create()
143 ->setValues($requiredParams)
144 ->setCheckPermissions(FALSE)
145 ->execute()
146 ->first();
147
148 $this->assertArrayHasKey('id', $createResult, "create missing ID");
149 $id = $createResult['id'];
150
151 $this->assertGreaterThanOrEqual(1, $id, "$entity ID not positive");
152
153 return $id;
154 }
155
156 /**
157 * @param \Civi\Api4\Generic\AbstractEntity|string $entityClass
158 * @param int $id
159 */
160 protected function checkUpdateFailsFromCreate($entityClass, $id) {
161 $exceptionThrown = '';
162 try {
163 $entityClass::create()
164 ->setCheckPermissions(FALSE)
165 ->addValue('id', $id)
166 ->execute();
167 }
168 catch (\API_Exception $e) {
169 $exceptionThrown = $e->getMessage();
170 }
171 $this->assertContains('id', $exceptionThrown);
172 }
173
174 /**
175 * @param \Civi\Api4\Generic\AbstractEntity|string $entityClass
176 * @param int $id
177 * @param string $entity
178 */
179 protected function checkGet($entityClass, $id, $entity) {
180 $getResult = $entityClass::get()
181 ->setCheckPermissions(FALSE)
182 ->addWhere('id', '=', $id)
183 ->execute();
184
185 $errMsg = sprintf('Failed to fetch a %s after creation', $entity);
186 $this->assertEquals($id, $getResult->first()['id'], $errMsg);
187 $this->assertEquals(1, $getResult->count(), $errMsg);
188 }
189
190 /**
191 * @param \Civi\Api4\Generic\AbstractEntity|string $entityClass
192 * @param int $id
193 * @param string $entity
194 */
195 protected function checkGetCount($entityClass, $id, $entity) {
196 $getResult = $entityClass::get()
197 ->setCheckPermissions(FALSE)
198 ->addWhere('id', '=', $id)
199 ->selectRowCount()
200 ->execute();
201 $errMsg = sprintf('%s getCount failed', $entity);
202 $this->assertEquals(1, $getResult->count(), $errMsg);
203
204 $getResult = $entityClass::get()
205 ->setCheckPermissions(FALSE)
206 ->selectRowCount()
207 ->execute();
208 $errMsg = sprintf('%s getCount failed', $entity);
209 $this->assertGreaterThanOrEqual(1, $getResult->count(), $errMsg);
210 }
211
212 /**
213 * @param \Civi\Api4\Generic\AbstractEntity|string $entityClass
214 */
215 protected function checkDeleteWithNoId($entityClass) {
216 $exceptionThrown = '';
217 try {
218 $entityClass::delete()
219 ->execute();
220 }
221 catch (\API_Exception $e) {
222 $exceptionThrown = $e->getMessage();
223 }
224 $this->assertContains('required', $exceptionThrown);
225 }
226
227 /**
228 * @param \Civi\Api4\Generic\AbstractEntity|string $entityClass
229 */
230 protected function checkWrongParamType($entityClass) {
231 $exceptionThrown = '';
232 try {
233 $entityClass::get()
234 ->setCheckPermissions('nada')
235 ->execute();
236 }
237 catch (\API_Exception $e) {
238 $exceptionThrown = $e->getMessage();
239 }
240 $this->assertContains('checkPermissions', $exceptionThrown);
241 $this->assertContains('type', $exceptionThrown);
242 }
243
244 /**
245 * @param \Civi\Api4\Generic\AbstractEntity|string $entityClass
246 * @param int $id
247 */
248 protected function checkDeletion($entityClass, $id) {
249 $deleteResult = $entityClass::delete()
250 ->setCheckPermissions(FALSE)
251 ->addWhere('id', '=', $id)
252 ->execute();
253
254 // should get back an array of deleted id
255 $this->assertEquals([['id' => $id]], (array) $deleteResult);
256 }
257
258 /**
259 * @param \Civi\Api4\Generic\AbstractEntity|string $entityClass
260 * @param int $id
261 * @param string $entity
262 */
263 protected function checkPostDelete($entityClass, $id, $entity) {
264 $getDeletedResult = $entityClass::get()
265 ->setCheckPermissions(FALSE)
266 ->addWhere('id', '=', $id)
267 ->execute();
268
269 $errMsg = sprintf('Entity "%s" was not deleted', $entity);
270 $this->assertEquals(0, count($getDeletedResult), $errMsg);
271 }
272
273}