Set version to 5.1.beta1
[civicrm-core.git] / tests / phpunit / CRM / Mailing / BAO / MailingTest.php
CommitLineData
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 */
31class 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}