commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-new / civicrm / tests / phpunit / CRM / Contact / BAO / GroupContactCacheTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
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 * Test class for CRM_Contact_BAO_GroupContact BAO
30 *
31 * @package CiviCRM
32 */
33 class CRM_Contact_BAO_GroupContactCacheTest extends CiviUnitTestCase {
34
35 /**
36 * Manually add and remove contacts from a smart group.
37 */
38 public function testManualAddRemove() {
39 // Create smart group $g
40 $params = array(
41 'name' => 'Deceased Contacts',
42 'title' => 'Deceased Contacts',
43 'is_active' => 1,
44 'formValues' => array('is_deceased' => 1),
45 );
46 $group = CRM_Contact_BAO_Group::createSmartGroup($params);
47 $this->registerTestObjects(array($group));
48
49 // Create contacts $y1, $y2, $y3 which do match $g; create $n1, $n2, $n3 which do not match $g
50 $living = $this->createTestObject('CRM_Contact_DAO_Contact', array('is_deceased' => 0), 3);
51 $deceased = $this->createTestObject('CRM_Contact_DAO_Contact', array('is_deceased' => 1), 3);
52 $this->assertEquals(3, count($deceased));
53 $this->assertEquals(3, count($living));
54
55 // Assert: $g cache has exactly $y1, $y2, $y3
56 CRM_Contact_BAO_GroupContactCache::load($group, TRUE);
57 $this->assertCacheMatches(
58 array($deceased[0]->id, $deceased[1]->id, $deceased[2]->id),
59 $group->id
60 );
61
62 // Add $n1 to $g
63 $this->callAPISuccess('group_contact', 'create', array(
64 'contact_id' => $living[0]->id,
65 'group_id' => $group->id,
66 ));
67
68 CRM_Contact_BAO_GroupContactCache::load($group, TRUE);
69 $this->assertCacheMatches(
70 array($deceased[0]->id, $deceased[1]->id, $deceased[2]->id, $living[0]->id),
71 $group->id
72 );
73
74 // Remove $y1 from $g
75 $this->callAPISuccess('group_contact', 'create', array(
76 'contact_id' => $deceased[0]->id,
77 'group_id' => $group->id,
78 'status' => 'Removed',
79 ));
80
81 CRM_Contact_BAO_GroupContactCache::load($group, TRUE);
82 $this->assertCacheMatches(
83 array(
84 $deceased[1]->id,
85 $deceased[2]->id,
86 $living[0]->id,
87 ),
88 $group->id
89 );
90 }
91
92 /**
93 * Allow removing contact from a parent group even if contact is in a child group. (CRM-8858).
94 */
95 public function testRemoveFromParentSmartGroup() {
96 // Create smart group $parent
97 $params = array(
98 'name' => 'Deceased Contacts',
99 'title' => 'Deceased Contacts',
100 'is_active' => 1,
101 'formValues' => array('is_deceased' => 1),
102 );
103 $parent = CRM_Contact_BAO_Group::createSmartGroup($params);
104 $this->registerTestObjects(array($parent));
105
106 // Create group $child in $parent
107 $params = array(
108 'name' => 'Child Group',
109 'title' => 'Child Group',
110 'is_active' => 1,
111 'parents' => array($parent->id => 1),
112 );
113 $child = CRM_Contact_BAO_Group::create($params);
114 $this->registerTestObjects(array($child));
115
116 // Create $c1, $c2, $c3
117 $deceased = $this->createTestObject('CRM_Contact_DAO_Contact', array('is_deceased' => 1), 3);
118
119 // Add $c1, $c2, $c3 to $child
120 foreach ($deceased as $contact) {
121 $this->callAPISuccess('group_contact', 'create', array(
122 'contact_id' => $contact->id,
123 'group_id' => $child->id,
124 ));
125 }
126
127 CRM_Contact_BAO_GroupContactCache::load($parent, TRUE);
128 $this->assertCacheMatches(
129 array($deceased[0]->id, $deceased[1]->id, $deceased[2]->id),
130 $parent->id
131 );
132
133 // Remove $c1 from $parent
134 $this->callAPISuccess('group_contact', 'create', array(
135 'contact_id' => $deceased[0]->id,
136 'group_id' => $parent->id,
137 'status' => 'Removed',
138 ));
139
140 // Assert $c1 not in $parent
141 CRM_Contact_BAO_GroupContactCache::load($parent, TRUE);
142 $this->assertCacheMatches(
143 array(
144 $deceased[1]->id,
145 $deceased[2]->id,
146 ),
147 $parent->id
148 );
149
150 // Assert $c1 still in $child
151 $this->assertDBQuery(1,
152 'select count(*) from civicrm_group_contact where group_id=%1 and contact_id=%2 and status=%3',
153 array(
154 1 => array($child->id, 'Integer'),
155 2 => array($deceased[0]->id, 'Integer'),
156 3 => array('Added', 'String'),
157 )
158 );
159 }
160
161 /**
162 * Assert that the cache for a group contains exactly the listed contacts.
163 *
164 * @param array $expectedContactIds
165 * Array(int).
166 * @param int $groupId
167 */
168 public function assertCacheMatches($expectedContactIds, $groupId) {
169 $sql = 'SELECT contact_id FROM civicrm_group_contact_cache WHERE group_id = %1';
170 $params = array(1 => array($groupId, 'Integer'));
171 $dao = CRM_Core_DAO::executeQuery($sql, $params);
172 $actualContactIds = array();
173 while ($dao->fetch()) {
174 $actualContactIds[] = $dao->contact_id;
175 }
176
177 sort($expectedContactIds);
178 sort($actualContactIds);
179 $this->assertEquals($expectedContactIds, $actualContactIds);
180 }
181
182 // *** Everything below this should be moved to parent class ****
183
184 /**
185 * @var array(DAO_Name => array(int)) List of items to garbage-collect during tearDown
186 */
187 private $_testObjects;
188
189 /**
190 * Sets up the fixture, for example, opens a network connection.
191 *
192 * This method is called before a test is executed.
193 */
194 protected function setUp() {
195 $this->_testObjects = array();
196 parent::setUp();
197 }
198
199 /**
200 * Tears down the fixture, for example, closes a network connection.
201 *
202 * This method is called after a test is executed.
203 */
204 protected function tearDown() {
205 parent::tearDown();
206 $this->deleteTestObjects();
207 }
208
209 /**
210 * This is a wrapper for CRM_Core_DAO::createTestObject which tracks created entities.
211 *
212 * @see CRM_Core_DAO::createTestObject
213 *
214 * @param string $daoName
215 * @param array $params
216 * @param int $numObjects
217 * @param bool $createOnly
218 *
219 * @return array|NULL|object
220 */
221 public function createTestObject($daoName, $params = array(), $numObjects = 1, $createOnly = FALSE) {
222 $objects = CRM_Core_DAO::createTestObject($daoName, $params, $numObjects, $createOnly);
223 if (is_array($objects)) {
224 $this->registerTestObjects($objects);
225 }
226 else {
227 $this->registerTestObjects(array($objects));
228 }
229 return $objects;
230 }
231
232 /**
233 * Register test objects.
234 *
235 * @param array $objects
236 * DAO or BAO objects.
237 */
238 public function registerTestObjects($objects) {
239 foreach ($objects as $object) {
240 $daoName = preg_replace('/_BAO_/', '_DAO_', get_class($object));
241 $this->_testObjects[$daoName][] = $object->id;
242 }
243 }
244
245 /**
246 * Delete test objects.
247 *
248 * Note: You might argue that the FK relations between test
249 * objects could make this problematic; however, it should
250 * behave intuitively as long as we mentally split our
251 * test-objects between the "manual/primary records"
252 * and the "automatic/secondary records"
253 */
254 public function deleteTestObjects() {
255 foreach ($this->_testObjects as $daoName => $daoIds) {
256 foreach ($daoIds as $daoId) {
257 CRM_Core_DAO::deleteTestObjects($daoName, array('id' => $daoId));
258 }
259 }
260 $this->_testObjects = array();
261 }
262
263 }