ebe220b5849254a94e245b966d848c35e8987863
[civicrm-core.git] / tests / phpunit / api / v4 / UnitTestCase.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 * $Id$
18 *
19 */
20
21
22 namespace api\v4;
23
24 use api\v4\Traits\TestDataLoaderTrait;
25 use Civi\Test\HeadlessInterface;
26 use Civi\Test\TransactionalInterface;
27
28 require_once 'api/Exception.php';
29
30 /**
31 * @group headless
32 */
33 class UnitTestCase extends \PHPUnit\Framework\TestCase implements HeadlessInterface, TransactionalInterface {
34
35 use TestDataLoaderTrait;
36
37 /**
38 * @see CiviUnitTestCase
39 *
40 * @param string $name
41 * @param array $data
42 * @param string $dataName
43 */
44 public function __construct($name = NULL, array $data = [], $dataName = '') {
45 parent::__construct($name, $data, $dataName);
46 error_reporting(E_ALL & ~E_NOTICE);
47 }
48
49 public function setUpHeadless() {
50 return \Civi\Test::headless()->apply();
51 }
52
53 /**
54 * Tears down the fixture, for example, closes a network connection.
55 *
56 * This method is called after a test is executed.
57 */
58 public function tearDown() {
59 parent::tearDown();
60 }
61
62 /**
63 * Quick clean by emptying tables created for the test.
64 *
65 * @param array $params
66 */
67 public function cleanup($params) {
68 $params += [
69 'tablesToTruncate' => [],
70 ];
71 \CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 0;");
72 foreach ($params['tablesToTruncate'] as $table) {
73 \Civi::log()->info('truncating: ' . $table);
74 $sql = "TRUNCATE TABLE $table";
75 \CRM_Core_DAO::executeQuery($sql);
76 }
77 \CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 1;");
78 }
79
80 /**
81 * Quick record counter
82 *
83 * @param string $table_name
84 * @returns int record count
85 */
86 public function getRowCount($table_name) {
87 $sql = "SELECT count(id) FROM $table_name";
88 return (int) \CRM_Core_DAO::singleValueQuery($sql);
89 }
90
91 /**
92 * Create sample entities (using V3 for now).
93 *
94 * @param array $params
95 * (type, seq, overrides, count)
96 * @return array
97 * (either single, or array of array if count >1)
98 * @throws \CiviCRM_API3_Exception
99 * @throws \Exception
100 */
101 public static function createEntity($params) {
102 $params += [
103 'count' => 1,
104 'seq' => 0,
105 ];
106 $entities = [];
107 $entity = NULL;
108 for ($i = 0; $i < $params['count']; $i++) {
109 $params['seq']++;
110 $data = self::sample($params);
111 $api_params = ['sequential' => 1] + $data['sample_params'];
112 $result = civicrm_api3($data['entity'], 'create', $api_params);
113 if ($result['is_error']) {
114 throw new \Exception("creating $data[entity] failed");
115 }
116 $entity = $result['values'][0];
117 if (!($entity['id'] > 0)) {
118 throw new \Exception("created entity is malformed");
119 }
120 $entities[] = $entity;
121 }
122 return $params['count'] == 1 ? $entity : $entities;
123 }
124
125 /**
126 * Helper function for creating sample entities.
127 *
128 * Depending on the supplied sequence integer, plucks values from the dummy data.
129 * Constructs a foreign entity when an ID is required but isn't supplied in the overrides.
130 *
131 * Inspired by CiviUnitTestCase::
132 * @todo - extract this function to own class and share with CiviUnitTestCase?
133 * @param array $params
134 * - type: string roughly matching entity type
135 * - seq: (optional) int sequence number for the values of this type
136 * - overrides: (optional) array of fill in parameters
137 *
138 * @return array
139 * - entity: string API entity type (usually the type supplied except for contact subtypes)
140 * - sample_params: array API sample_params properties of sample entity
141 */
142 public static function sample($params) {
143 $params += [
144 'seq' => 0,
145 'overrides' => [],
146 ];
147 $type = $params['type'];
148 // sample data - if field is array then chosed based on `seq`
149 $sample_params = [];
150 if (in_array($type, ['Individual', 'Organization', 'Household'])) {
151 $sample_params['contact_type'] = $type;
152 $entity = 'Contact';
153 }
154 else {
155 $entity = $type;
156 }
157 // use the seq to pluck a set of params out
158 foreach (self::sampleData($type) as $key => $value) {
159 if (is_array($value)) {
160 $sample_params[$key] = $value[$params['seq'] % count($value)];
161 }
162 else {
163 $sample_params[$key] = $value;
164 }
165 }
166 if ($type == 'Individual') {
167 $sample_params['email'] = strtolower(
168 $sample_params['first_name'] . '_' . $sample_params['last_name'] . '@civicrm.org'
169 );
170 $sample_params['prefix_id'] = 3;
171 $sample_params['suffix_id'] = 3;
172 }
173 if (!count($sample_params)) {
174 throw new \Exception("unknown sample type: $type");
175 }
176 $sample_params = $params['overrides'] + $sample_params;
177 // make foreign enitiies if they haven't been supplied
178 foreach ($sample_params as $key => $value) {
179 if (substr($value, 0, 6) === 'dummy.') {
180 $foreign_entity = self::createEntity([
181 'type' => substr($value, 6),
182 'seq' => $params['seq'],
183 ]);
184 $sample_params[$key] = $foreign_entity['id'];
185 }
186 }
187 return compact("entity", "sample_params");
188 }
189
190 /**
191 * Provider of sample data.
192 *
193 * @return array
194 * Array values represent a set of allowable items.
195 * Strings in the form "dummy.Entity" require creating a foreign entity first.
196 */
197 public static function sampleData($type) {
198 $data = [
199 'Individual' => [
200 // The number of values in each list need to be coprime numbers to not have duplicates
201 'first_name' => ['Anthony', 'Joe', 'Terrence', 'Lucie', 'Albert', 'Bill', 'Kim'],
202 'middle_name' => ['J.', 'M.', 'P', 'L.', 'K.', 'A.', 'B.', 'C.', 'D', 'E.', 'Z.'],
203 'last_name' => ['Anderson', 'Miller', 'Smith', 'Collins', 'Peterson'],
204 'contact_type' => 'Individual',
205 ],
206 'Organization' => [
207 'organization_name' => [
208 'Unit Test Organization',
209 'Acme',
210 'Roberts and Sons',
211 'Cryo Space Labs',
212 'Sharper Pens',
213 ],
214 ],
215 'Household' => [
216 'household_name' => ['Unit Test household'],
217 ],
218 'Event' => [
219 'title' => 'Annual CiviCRM meet',
220 'summary' => 'If you have any CiviCRM related issues or want to track where CiviCRM is heading, Sign up now',
221 'description' => 'This event is intended to give brief idea about progess of CiviCRM and giving solutions to common user issues',
222 'event_type_id' => 1,
223 'is_public' => 1,
224 'start_date' => 20081021,
225 'end_date' => 20081023,
226 'is_online_registration' => 1,
227 'registration_start_date' => 20080601,
228 'registration_end_date' => 20081015,
229 'max_participants' => 100,
230 'event_full_text' => 'Sorry! We are already full',
231 'is_monetary' => 0,
232 'is_active' => 1,
233 'is_show_location' => 0,
234 ],
235 'Participant' => [
236 'event_id' => 'dummy.Event',
237 'contact_id' => 'dummy.Individual',
238 'status_id' => 2,
239 'role_id' => 1,
240 'register_date' => 20070219,
241 'source' => 'Wimbeldon',
242 'event_level' => 'Payment',
243 ],
244 'Contribution' => [
245 'contact_id' => 'dummy.Individual',
246 // donation, 2 = member, 3 = campaign contribution, 4=event
247 'financial_type_id' => 1,
248 'total_amount' => 7.3,
249 ],
250 'Activity' => [
251 //'activity_type_id' => 1,
252 'subject' => 'unit testing',
253 'source_contact_id' => 'dummy.Individual',
254 ],
255 ];
256 if ($type == 'Contact') {
257 $type = 'Individual';
258 }
259 return $data[$type];
260 }
261
262 }