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