Merge pull request #7728 from andrew-cormick-dockery/CRM-17959
[civicrm-core.git] / tests / phpunit / api / v3 / MailingABTest.php
1 <?php
2 /*
3 * File for the TestMailing class
4 *
5 * (PHP 5)
6 *
7 * @package CiviCRM
8 *
9 * This file is part of CiviCRM
10 *
11 * CiviCRM is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Affero General Public License
13 * as published by the Free Software Foundation; either version 3 of
14 * the License, or (at your option) any later version.
15 *
16 * CiviCRM is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Affero General Public License for more details.
20 *
21 * You should have received a copy of the GNU Affero General Public
22 * License along with this program. If not, see
23 * <http://www.gnu.org/licenses/>.
24 */
25
26 /**
27 * Test APIv3 civicrm_mailingab_* functions
28 *
29 * @package CiviCRM
30 * @group headless
31 */
32 class api_v3_MailingABTest extends CiviUnitTestCase {
33 protected $_mailingID_A;
34 protected $_mailingID_B;
35 protected $_mailingID_C;
36 protected $_params;
37 protected $_apiversion = 3;
38 protected $_entity = 'MailingAB';
39 protected $_groupID;
40
41 public function setUp() {
42 parent::setUp();
43 $this->useTransaction(TRUE);
44 $this->createLoggedInUser();
45 $this->_mailingID_A = $this->createMailing();
46 $this->_mailingID_B = $this->createMailing();
47 $this->_mailingID_C = $this->createMailing();
48 $this->_groupID = $this->groupCreate();
49
50 $this->_params = array(
51 'mailing_id_a' => $this->_mailingID_A,
52 'mailing_id_b' => $this->_mailingID_B,
53 'mailing_id_c' => $this->_mailingID_C,
54 'testing_criteria' => 'subject',
55 'winner_criteria' => 'open',
56 'declare_winning_time' => '+2 days',
57 'group_percentage' => 10,
58 );
59 }
60
61 /**
62 * Test civicrm_mailing_create.
63 */
64 public function testMailingABCreateSuccess() {
65 $result = $this->callAPIAndDocument($this->_entity, 'create', $this->_params, __FUNCTION__, __FILE__);
66 $this->assertTrue(is_numeric($result['id']), "In line " . __LINE__);
67 $this->assertEquals($this->_params['group_percentage'], $result['values'][$result['id']]['group_percentage']);
68 }
69
70 /**
71 * Test civicrm_mailing_delete.
72 */
73 public function testMailerDeleteSuccess() {
74 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
75
76 $this->assertDBQuery(1, "SELECT count(*) FROM civicrm_mailing_abtest WHERE id = %1", array(
77 1 => array($result['id'], 'Integer'),
78 ));
79 $this->assertDBQuery(3, "SELECT count(*) FROM civicrm_mailing WHERE id IN (%1,%2,%3)", array(
80 1 => array($this->_mailingID_A, 'Integer'),
81 2 => array($this->_mailingID_B, 'Integer'),
82 3 => array($this->_mailingID_C, 'Integer'),
83 ));
84
85 $this->callAPISuccess($this->_entity, 'delete', array('id' => $result['id']));
86
87 $this->assertDBQuery(0, "SELECT count(*) FROM civicrm_mailing_abtest WHERE id = %1", array(
88 1 => array($result['id'], 'Integer'),
89 ));
90 $this->assertDBQuery(0, "SELECT count(*) FROM civicrm_mailing WHERE id IN (%1,%2,%3)", array(
91 1 => array($this->_mailingID_A, 'Integer'),
92 2 => array($this->_mailingID_B, 'Integer'),
93 3 => array($this->_mailingID_C, 'Integer'),
94 ));
95 }
96
97 /**
98 * @return array
99 */
100 public function groupPctProvider() {
101 $cases = array(); // array(int $totalSize, int $groupPct, int $expectedCountA, $expectedCountB, $expectedCountC)
102 $cases[] = array(400, 7, 28, 28, 344);
103 $cases[] = array(100, 10, 10, 10, 80);
104 $cases[] = array(50, 20, 10, 10, 30);
105 $cases[] = array(50, 10, 5, 5, 40);
106 $cases[] = array(3, 10, 1, 1, 1);
107 $cases[] = array(2, 10, 1, 1, 0);
108 $cases[] = array(1, 10, 1, 0, 0);
109 return $cases;
110 }
111
112 /**
113 * Create a test and ensure that all three mailings (A/B/C) wind up with the correct
114 * number of recipients.
115 *
116 * @param $totalGroupContacts
117 * @param $groupPct
118 * @param $expectedCountA
119 * @param $expectedCountB
120 * @param $expectedCountC
121 * @dataProvider groupPctProvider
122 */
123 public function testDistribution($totalGroupContacts, $groupPct, $expectedCountA, $expectedCountB, $expectedCountC) {
124
125 $result = $this->groupContactCreate($this->_groupID, $totalGroupContacts);
126 $this->assertEquals($totalGroupContacts, $result['added'], "in line " . __LINE__);
127
128 $params = $this->_params;
129 $params['group_percentage'] = $groupPct;
130 $result = $this->callAPISuccess($this->_entity, 'create', $params);
131
132 $this->callAPISuccess('Mailing', 'create', array(
133 'id' => $this->_mailingID_A,
134 'groups' => array('include' => array($this->_groupID)),
135 ));
136 $this->assertJobCounts(0, 0, 0);
137
138 $this->callAPISuccess('MailingAB', 'submit', array(
139 'id' => $result['id'],
140 'status' => 'Testing',
141 'scheduled_date' => date('YmdHis'),
142 'approval_date' => date('YmdHis'),
143 ));
144 $this->assertRecipientCounts($expectedCountA, $expectedCountB, $expectedCountC);
145 $this->assertJobCounts(1, 1, 0);
146
147 $this->callAPISuccess('MailingAB', 'submit', array(
148 'id' => $result['id'],
149 'status' => 'Final',
150 'scheduled_date' => date('YmdHis'),
151 'approval_date' => date('YmdHis'),
152 ));
153 $this->assertRecipientCounts($expectedCountA, $expectedCountB, $expectedCountC);
154 $this->assertJobCounts(1, 1, 1);
155 }
156
157 /**
158 * @param $expectedCountA
159 * @param $expectedCountB
160 * @param $expectedCountC
161 */
162 protected function assertRecipientCounts($expectedCountA, $expectedCountB, $expectedCountC) {
163 $countA = $this->callAPISuccess('MailingRecipients', 'getcount', array('mailing_id' => $this->_mailingID_A));
164 $countB = $this->callAPISuccess('MailingRecipients', 'getcount', array('mailing_id' => $this->_mailingID_B));
165 $countC = $this->callAPISuccess('MailingRecipients', 'getcount', array('mailing_id' => $this->_mailingID_C));
166 $this->assertEquals($expectedCountA, $countA, "check mailing recipients A in line " . __LINE__);
167 $this->assertEquals($expectedCountB, $countB, "check mailing recipients B in line " . __LINE__);
168 $this->assertEquals($expectedCountC, $countC, "check mailing recipients C in line " . __LINE__);
169 }
170
171 /**
172 * @param $expectedA
173 * @param $expectedB
174 * @param $expectedC
175 */
176 protected function assertJobCounts($expectedA, $expectedB, $expectedC) {
177 $this->assertDBQuery($expectedA, 'SELECT count(*) FROM civicrm_mailing_job WHERE mailing_id = %1', array(
178 1 => array(
179 $this->_mailingID_A,
180 'Integer',
181 ),
182 ));
183 $this->assertDBQuery($expectedB, 'SELECT count(*) FROM civicrm_mailing_job WHERE mailing_id = %1', array(
184 1 => array(
185 $this->_mailingID_B,
186 'Integer',
187 ),
188 ));
189 $this->assertDBQuery($expectedC, 'SELECT count(*) FROM civicrm_mailing_job WHERE mailing_id = %1', array(
190 1 => array(
191 $this->_mailingID_C,
192 'Integer',
193 ),
194 ));
195 }
196
197 }