Commit | Line | Data |
---|---|---|
9f0a25d7 J |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
4 | | CiviCRM version 4.7 | | |
5 | +--------------------------------------------------------------------+ | |
8c9251b3 | 6 | | Copyright CiviCRM LLC (c) 2004-2018 | |
9f0a25d7 J |
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 | +--------------------------------------------------------------------+ | |
26 | */ | |
27 | ||
28 | /** | |
29 | * Class CRM_Mailing_BAO_MailingTest | |
30 | */ | |
31 | class CRM_Mailing_BAO_MailingTest extends CiviUnitTestCase { | |
32 | ||
33 | public function setUp() { | |
34 | parent::setUp(); | |
35 | } | |
36 | ||
df3320dc | 37 | public function tearDown() { |
38 | global $dbLocale; | |
39 | if ($dbLocale) { | |
40 | CRM_Core_I18n_Schema::makeSinglelingual('en_US'); | |
41 | } | |
42 | parent::tearDown(); | |
43 | } | |
44 | ||
6ff6f4f2 J |
45 | /** |
46 | * Helper function to assert whether the calculated recipients of a mailing | |
47 | * match the expected list | |
48 | * | |
49 | * @param $mailingID | |
50 | * @param $expectedRecipients array | |
51 | * Array of contact ID that should be in the recipient list. | |
52 | */ | |
53 | private function assertRecipientsCorrect($mailingID, $expectedRecipients) { | |
54 | ||
55 | // Reset keys to ensure match | |
56 | $expectedRecipients = array_values($expectedRecipients); | |
57 | ||
58 | // Load the recipients as a list of contact IDs | |
59 | CRM_Mailing_BAO_Mailing::getRecipients($mailingID); | |
60 | $recipients = $this->callAPISuccess('MailingRecipients', 'get', array('mailing_id' => $mailingID)); | |
61 | $contactIDs = array(); | |
62 | foreach ($recipients['values'] as $recipient) { | |
63 | $contactIDs[] = $recipient['contact_id']; | |
64 | } | |
65 | ||
66 | // Check the lists match | |
67 | $this->assertTreeEquals($expectedRecipients, $contactIDs); | |
68 | } | |
69 | ||
70 | /** | |
71 | * Helper function to create a mailing include/exclude group. | |
72 | * | |
73 | * @param $mailingID | |
74 | * @param $groupID | |
75 | * @param string $type | |
76 | * @return array|int | |
77 | */ | |
78 | private function createMailingGroup($mailingID, $groupID, $type = 'Include') { | |
79 | return $this->callAPISuccess('MailingGroup', 'create', array( | |
80 | 'mailing_id' => $mailingID, | |
81 | 'group_type' => $type, | |
df3320dc | 82 | 'entity_table' => CRM_Contact_BAO_Group::getTableName(), |
6ff6f4f2 J |
83 | 'entity_id' => $groupID, |
84 | )); | |
85 | } | |
86 | ||
251a8849 | 87 | /** |
7ff80daf J |
88 | * @todo Missing tests: |
89 | * - Ensure opt out emails are not mailed | |
90 | * - Ensure 'stop' emails are not mailed | |
91 | * - Ensure the deceased are not mailed | |
92 | * - Tests for getLocationFilterAndOrderBy (selecting correct 'type') | |
93 | * - ... | |
251a8849 J |
94 | */ |
95 | ||
7ff80daf J |
96 | /** |
97 | * Test to ensure that static and smart mailing groups can be added to an | |
98 | * email mailing as 'include' or 'exclude' groups - and the members are | |
99 | * included or excluded appropriately. | |
100 | * | |
101 | * contact 0 : static 0 (inc) + smart 5 (exc) | |
102 | * contact 1 : static 0 (inc) | |
103 | * contact 2 : static 1 (inc) | |
104 | * contact 3 : static 1 (inc) | |
105 | * contact 4 : static 2 (exc) + smart 3 (inc) | |
106 | * contact 5 : smart 3 (inc) | |
107 | * contact 6 : smart 4 (inc) | |
108 | * contact 7 : smart 4 (inc) | |
109 | */ | |
110 | public function testgetRecipientsEmailGroupIncludeExclude() { | |
7ff80daf J |
111 | // Set up groups; 3 standard, 3 smart |
112 | $groupIDs = array(); | |
113 | for ($i = 0; $i < 6; $i++) { | |
114 | $params = array( | |
115 | 'name' => 'Test static group ' . $i, | |
116 | 'title' => 'Test static group ' . $i, | |
117 | 'is_active' => 1, | |
118 | ); | |
119 | if ($i < 3) { | |
120 | $groupIDs[$i] = $this->groupCreate($params); | |
121 | } | |
122 | else { | |
123 | $groupIDs[$i] = $this->smartGroupCreate(array( | |
124 | 'formValues' => array('last_name' => 'smart' . $i), | |
125 | ), $params); | |
126 | } | |
127 | } | |
128 | ||
129 | // Create contacts | |
130 | $contactIDs = array( | |
131 | 0 => $this->individualCreate(array('last_name' => 'smart5'), 0), | |
132 | 1 => $this->individualCreate(array(), 1), | |
133 | 2 => $this->individualCreate(array(), 2), | |
134 | 3 => $this->individualCreate(array(), 3), | |
135 | 4 => $this->individualCreate(array('last_name' => 'smart3'), 4), | |
136 | 5 => $this->individualCreate(array('last_name' => 'smart3'), 5), | |
137 | 6 => $this->individualCreate(array('last_name' => 'smart4'), 6), | |
138 | 7 => $this->individualCreate(array('last_name' => 'smart4'), 7), | |
139 | ); | |
140 | ||
141 | // Add contacts to static groups | |
142 | $this->callAPISuccess('GroupContact', 'Create', array( | |
143 | 'group_id' => $groupIDs[0], | |
144 | 'contact_id' => $contactIDs[0], | |
145 | )); | |
146 | $this->callAPISuccess('GroupContact', 'Create', array( | |
147 | 'group_id' => $groupIDs[0], | |
148 | 'contact_id' => $contactIDs[1], | |
149 | )); | |
150 | $this->callAPISuccess('GroupContact', 'Create', array( | |
151 | 'group_id' => $groupIDs[1], | |
152 | 'contact_id' => $contactIDs[2], | |
153 | )); | |
154 | $this->callAPISuccess('GroupContact', 'Create', array( | |
155 | 'group_id' => $groupIDs[1], | |
156 | 'contact_id' => $contactIDs[3], | |
157 | )); | |
158 | $this->callAPISuccess('GroupContact', 'Create', array( | |
159 | 'group_id' => $groupIDs[2], | |
160 | 'contact_id' => $contactIDs[4], | |
161 | )); | |
162 | ||
163 | // Force rebuild the smart groups | |
164 | for ($i = 3; $i < 6; $i++) { | |
165 | $group = new CRM_Contact_DAO_Group(); | |
166 | $group->id = $groupIDs[$i]; | |
167 | $group->find(TRUE); | |
168 | CRM_Contact_BAO_GroupContactCache::load($group, TRUE); | |
169 | } | |
170 | ||
171 | // Check that we can include static groups in the mailing. | |
172 | // Expected: Contacts [0-3] should be included. | |
173 | $mailing = $this->callAPISuccess('Mailing', 'create', array()); | |
174 | $this->createMailingGroup($mailing['id'], $groupIDs[0]); | |
175 | $this->createMailingGroup($mailing['id'], $groupIDs[1]); | |
176 | $expected = $contactIDs; | |
177 | unset($expected[4], $expected[5], $expected[6], $expected[7]); | |
178 | $this->assertRecipientsCorrect($mailing['id'], $expected); | |
179 | ||
180 | // Check that we can include smart groups in the mailing too. | |
181 | // Expected: All contacts should be included. | |
df3320dc | 182 | // Also (dev/mail/6): Enable multilingual mode to check that restructing group doesn't affect recipient rebuilding |
183 | $this->enableMultilingual(); | |
7ff80daf J |
184 | $this->createMailingGroup($mailing['id'], $groupIDs[3]); |
185 | $this->createMailingGroup($mailing['id'], $groupIDs[4]); | |
186 | $this->assertRecipientsCorrect($mailing['id'], $contactIDs); | |
187 | ||
188 | // Check we can exclude static groups from the mailing. | |
189 | // Expected: All contacts except [4] | |
190 | $this->createMailingGroup($mailing['id'], $groupIDs[2], 'Exclude'); | |
191 | $expected = $contactIDs; | |
192 | unset($expected[4]); | |
193 | $this->assertRecipientsCorrect($mailing['id'], $expected); | |
194 | ||
195 | // Check we can exclude smart groups from the mailing too. | |
196 | // Expected: All contacts except [0] and [4] | |
197 | $this->createMailingGroup($mailing['id'], $groupIDs[5], 'Exclude'); | |
198 | $expected = $contactIDs; | |
199 | unset($expected[0], $expected[4]); | |
200 | $this->assertRecipientsCorrect($mailing['id'], $expected); | |
201 | ||
202 | // Tear down: delete mailing, groups, contacts | |
203 | $this->deleteMailing($mailing['id']); | |
204 | foreach ($groupIDs as $groupID) { | |
205 | $this->groupDelete($groupID); | |
206 | } | |
207 | foreach ($contactIDs as $contactID) { | |
208 | $this->contactDelete($contactID); | |
209 | } | |
7ff80daf J |
210 | } |
211 | ||
9f0a25d7 | 212 | /** |
6f3a35e0 | 213 | * Test CRM_Mailing_BAO_Mailing::getRecipients() on sms mode |
9f0a25d7 | 214 | */ |
7ff80daf | 215 | public function testgetRecipientsSMS() { |
9f0a25d7 J |
216 | // Tests for SMS bulk mailing recipients |
217 | // +CRM-21320 Ensure primary mobile number is selected over non-primary | |
218 | ||
219 | // Setup | |
6f3a35e0 | 220 | $smartGroupParams = array( |
221 | 'formValues' => array('contact_type' => array('IN' => array('Individual'))), | |
222 | ); | |
223 | $group = $this->smartGroupCreate($smartGroupParams); | |
9f0a25d7 J |
224 | $sms_provider = $this->callAPISuccess('SmsProvider', 'create', array( |
225 | 'sequential' => 1, | |
226 | 'name' => 1, | |
227 | 'title' => "Test", | |
228 | 'username' => "Test", | |
229 | 'password' => "Test", | |
230 | 'api_type' => 1, | |
231 | 'is_active' => 1, | |
232 | )); | |
233 | ||
6f3a35e0 | 234 | // Create Contact 1 and add in group |
235 | $contactID1 = $this->individualCreate(array(), 0); | |
9f0a25d7 J |
236 | $this->callAPISuccess('GroupContact', 'Create', array( |
237 | 'group_id' => $group, | |
6f3a35e0 | 238 | 'contact_id' => $contactID1, |
9f0a25d7 J |
239 | )); |
240 | ||
6f3a35e0 | 241 | // Create contact 2 and add in group |
242 | $contactID2 = $this->individualCreate(array(), 1); | |
9f0a25d7 J |
243 | $this->callAPISuccess('GroupContact', 'Create', array( |
244 | 'group_id' => $group, | |
6f3a35e0 | 245 | 'contact_id' => $contactID2, |
9f0a25d7 J |
246 | )); |
247 | ||
6f3a35e0 | 248 | $contactIDPhoneRecords = array( |
249 | $contactID1 => array( | |
250 | 'primary_phone_id' => CRM_Utils_Array::value('id', $this->callAPISuccess('Phone', 'create', array( | |
251 | 'contact_id' => $contactID1, | |
252 | 'phone' => "01 01", | |
253 | 'location_type_id' => "Home", | |
254 | 'phone_type_id' => "Mobile", | |
255 | 'is_primary' => 1, | |
256 | ))), | |
257 | 'other_phone_id' => CRM_Utils_Array::value('id', $this->callAPISuccess('Phone', 'create', array( | |
258 | 'contact_id' => $contactID1, | |
259 | 'phone' => "01 02", | |
260 | 'location_type_id' => "Work", | |
261 | 'phone_type_id' => "Mobile", | |
262 | 'is_primary' => 0, | |
263 | ))), | |
264 | ), | |
251a8849 | 265 | // Create the non-primary with a lower ID than the primary, to test CRM-21320 |
6f3a35e0 | 266 | $contactID2 => array( |
251a8849 | 267 | 'other_phone_id' => CRM_Utils_Array::value('id', $this->callAPISuccess('Phone', 'create', array( |
6f3a35e0 | 268 | 'contact_id' => $contactID2, |
269 | 'phone' => "02 01", | |
270 | 'location_type_id' => "Home", | |
271 | 'phone_type_id' => "Mobile", | |
251a8849 | 272 | 'is_primary' => 0, |
6f3a35e0 | 273 | ))), |
251a8849 | 274 | 'primary_phone_id' => CRM_Utils_Array::value('id', $this->callAPISuccess('Phone', 'create', array( |
6f3a35e0 | 275 | 'contact_id' => $contactID2, |
276 | 'phone' => "02 02", | |
277 | 'location_type_id' => "Work", | |
278 | 'phone_type_id' => "Mobile", | |
251a8849 | 279 | 'is_primary' => 1, |
6f3a35e0 | 280 | ))), |
281 | ), | |
282 | ); | |
283 | ||
9f0a25d7 | 284 | // Prepare expected results |
6f3a35e0 | 285 | $checkPhoneIDs = array( |
286 | $contactID1 => $contactIDPhoneRecords[$contactID1]['primary_phone_id'], | |
287 | $contactID2 => $contactIDPhoneRecords[$contactID2]['primary_phone_id'], | |
9f0a25d7 J |
288 | ); |
289 | ||
290 | // Create mailing | |
291 | $mailing = $this->callAPISuccess('Mailing', 'create', array('sms_provider_id' => $sms_provider['id'])); | |
6ff6f4f2 | 292 | $mailingInclude = $this->createMailingGroup($mailing['id'], $group); |
9f0a25d7 J |
293 | |
294 | // Get recipients | |
6ff6f4f2 | 295 | CRM_Mailing_BAO_Mailing::getRecipients($mailing['id']); |
9f0a25d7 J |
296 | $recipients = $this->callAPISuccess('MailingRecipients', 'get', array('mailing_id' => $mailing['id'])); |
297 | ||
298 | // Check the count is correct | |
299 | $this->assertEquals(2, $recipients['count'], 'Check recipient count'); | |
300 | ||
301 | // Check we got the 'primary' mobile for both contacts | |
302 | foreach ($recipients['values'] as $value) { | |
6f3a35e0 | 303 | $this->assertEquals($value['phone_id'], $checkPhoneIDs[$value['contact_id']], 'Check correct phone number for contact ' . $value['contact_id']); |
9f0a25d7 J |
304 | } |
305 | ||
306 | // Tidy up | |
307 | $this->deleteMailing($mailing['id']); | |
308 | $this->callAPISuccess('SmsProvider', 'Delete', array('id' => $sms_provider['id'])); | |
309 | $this->groupDelete($group); | |
6f3a35e0 | 310 | $this->contactDelete($contactID1); |
311 | $this->contactDelete($contactID2); | |
9f0a25d7 J |
312 | } |
313 | ||
314 | } |