Merge pull request #18745 from seamuslee001/backdrop_session
[civicrm-core.git] / tests / phpunit / E2E / Core / PrevNextTest.php
CommitLineData
ab723d18
TO
1<?php
2
3namespace E2E\Core;
4
5/**
6 * Class PrevNextTest
7 *
8 * Check that the active prev-next service behaves as expected.
9 *
10 * @package E2E\Core
47113d77 11 * @group e2e ornery
ab723d18
TO
12 */
13class PrevNextTest extends \CiviEndToEndTestCase {
14
15 /**
16 * @var string
17 */
39b959db
SL
18 protected $cacheKey;
19
20 /**
21 * @var string
22 */
23 protected $cacheKeyB;
ab723d18
TO
24
25 /**
26 * @var \CRM_Core_PrevNextCache_Interface
27 */
28 protected $prevNext;
29
30 protected function setUp() {
31 parent::setUp();
32 $this->prevNext = \Civi::service('prevnext');
33 $this->cacheKey = 'PrevNextTest_' . \CRM_Utils_String::createRandom(16, \CRM_Utils_String::ALPHANUMERIC);
7cbfc706 34 $this->cacheKeyB = 'PrevNextTestb_' . \CRM_Utils_String::createRandom(16, \CRM_Utils_String::ALPHANUMERIC);
ab723d18
TO
35 $this->assertTrue(
36 \CRM_Core_DAO::singleValueQuery('SELECT count(*) FROM civicrm_contact') > 25,
37 'The contact table must have at least 25 records.'
38 );
39 }
40
41 protected function tearDown() {
42 \Civi::service('prevnext')->deleteItem(NULL, $this->cacheKey);
7cbfc706 43 \Civi::service('prevnext')->deleteItem(NULL, $this->cacheKeyB);
ab723d18
TO
44 }
45
46 public function testFillSql() {
47 $start = 0;
48 $prefillLimit = 25;
49 $sort = NULL;
50
ea714811 51 $query = new \CRM_Contact_BAO_Query([['sort_name', 'IS NOT NULL', 1, 0, 0]], NULL, NULL, FALSE, FALSE, 1, FALSE, TRUE, FALSE, NULL, 'AND');
ab723d18
TO
52 $sql = $query->searchQuery($start, $prefillLimit, $sort, FALSE, $query->_includeContactIds,
53 FALSE, TRUE, TRUE);
2c8b42d5 54 $selectSQL = "SELECT DISTINCT %1, contact_a.id, contact_a.sort_name";
ab723d18
TO
55 $sql = str_replace(array("SELECT contact_a.id as contact_id", "SELECT contact_a.id as id"), $selectSQL, $sql);
56
57 $this->assertTrue(
2c8b42d5 58 $this->prevNext->fillWithSql($this->cacheKey, $sql, [1 => [$this->cacheKey, 'String']]),
ab723d18
TO
59 "fillWithSql should return TRUE on success"
60 );
61
62 $this->assertEquals(25, $this->prevNext->getCount($this->cacheKey));
63 $this->assertEquals(0, $this->prevNext->getCount('not-a-key-' . $this->cacheKey));
64
65 $all = $this->prevNext->getSelection($this->cacheKey, 'getall')[$this->cacheKey];
66 $this->assertCount($prefillLimit, $all);
67 $this->assertCount($prefillLimit, array_unique(array_keys($all)));
68 $this->assertEquals([1], array_unique(array_values($all)));
69
70 $this->assertSelections([]);
71 }
72
73 public function testFillArray() {
74 $rowSetA = [
75 ['entity_id1' => 100, 'data' => 'Alice'],
76 ['entity_id1' => 400, 'data' => 'Bob'],
77 ['entity_id1' => 200, 'data' => 'Carol'],
78 ];
79 $rowSetB = [
80 ['entity_id1' => 300, 'data' => 'Dave'],
81 ];
82
83 $this->assertTrue(
84 $this->prevNext->fillWithArray($this->cacheKey, $rowSetA),
85 "fillWithArray should return TRUE on success"
86 );
87 $this->assertTrue(
88 $this->prevNext->fillWithArray($this->cacheKey, $rowSetB),
89 "fillWithArray should return TRUE on success"
90 );
91
92 $this->assertEquals(4, $this->prevNext->getCount($this->cacheKey));
93 $this->assertEquals(0, $this->prevNext->getCount('not-a-key-' . $this->cacheKey));
94
3e9cd8a8 95 $all = $this->assertSelections([100, 400, 200, 300], 'getall', $this->cacheKey);
ab723d18
TO
96 $this->assertEquals([1], array_unique(array_values($all)));
97
3e9cd8a8 98 $this->assertSelections([], 'get', $this->cacheKey);
ab723d18
TO
99 }
100
2ca46d4d
TO
101 public function testFetch() {
102 $this->testFillArray();
103
104 $cids = $this->prevNext->fetch($this->cacheKey, 0, 2);
105 $this->assertEquals([100, 400], $cids);
106
107 $cids = $this->prevNext->fetch($this->cacheKey, 0, 4);
108 $this->assertEquals([100, 400, 200, 300], $cids);
109
110 $cids = $this->prevNext->fetch($this->cacheKey, 2, 2);
111 $this->assertEquals([200, 300], $cids);
112 }
113
ab723d18
TO
114 public function getFillFunctions() {
115 return [
116 ['testFillSql'],
117 ['testFillArray'],
118 ];
119 }
120
121 /**
122 * Select and unselect one item.
123 *
124 * @dataProvider getFillFunctions
125 */
126 public function testMarkSelection_1($fillFunction) {
127 call_user_func([$this, $fillFunction]);
128
129 $all = $this->prevNext->getSelection($this->cacheKey, 'getall')[$this->cacheKey];
130 list ($id1, $id2) = array_keys($all);
131 $this->prevNext->markSelection($this->cacheKey, 'select', $id1);
132
133 $this->assertSelections([$id1]);
134
135 $this->prevNext->markSelection($this->cacheKey, 'unselect', $id1);
136 $this->assertSelections([]);
137 }
138
139 /**
140 * Select and unselect two items.
141 *
142 * @dataProvider getFillFunctions
143 */
144 public function testMarkSelection_2($fillFunction) {
145 call_user_func([$this, $fillFunction]);
146
147 $all = $this->prevNext->getSelection($this->cacheKey, 'getall')[$this->cacheKey];
148 list ($id1, $id2, $id3) = array_keys($all);
149
150 $this->prevNext->markSelection($this->cacheKey, 'select', [$id1, $id3]);
151 $this->assertSelections([$id1, $id3]);
152
153 $this->prevNext->markSelection($this->cacheKey, 'unselect', $id1);
154 $this->assertSelections([$id3]);
155
156 $this->prevNext->markSelection($this->cacheKey, 'select', $id2);
157 $this->assertSelections([$id2, $id3]);
158
159 $this->prevNext->markSelection($this->cacheKey, 'unselect');
160 $this->assertSelections([]);
161 }
162
163 /**
164 * Check the neighbors of the first item.
165 *
166 * @dataProvider getFillFunctions
167 */
168 public function testGetPosition_first($fillFunction) {
169 call_user_func([$this, $fillFunction]);
170
171 $all = $this->prevNext->getSelection($this->cacheKey, 'getall')[$this->cacheKey];
172 list ($id1, $id2, $id3) = array_keys($all);
173
174 $pos = $this->prevNext->getPositions($this->cacheKey, $id1);
175
176 $this->assertTrue((bool) $pos['foundEntry']);
177
178 $this->assertEquals($id2, $pos['next']['id1']);
179 $this->assertTrue(!empty($pos['next']['data']));
180
181 $this->assertTrue(!isset($pos['prev']));
182 }
183
184 /**
185 * Check the neighbors of a middle item.
186 *
187 * @dataProvider getFillFunctions
188 */
189 public function testGetPosition_middle($fillFunction) {
190 call_user_func([$this, $fillFunction]);
191
192 $all = $this->prevNext->getSelection($this->cacheKey, 'getall')[$this->cacheKey];
193 list ($id1, $id2, $id3) = array_keys($all);
194
195 $pos = $this->prevNext->getPositions($this->cacheKey, $id2);
196 $this->assertTrue((bool) $pos['foundEntry']);
197
198 $this->assertEquals($id3, $pos['next']['id1']);
199 $this->assertTrue(!empty($pos['next']['data']));
200
201 $this->assertEquals($id1, $pos['prev']['id1']);
202 $this->assertTrue(!empty($pos['prev']['data']));
203 }
204
205 /**
206 * Check the neighbors of the last item.
207 *
208 * @dataProvider getFillFunctions
209 */
210 public function testGetPosition_last($fillFunction) {
211 call_user_func([$this, $fillFunction]);
212
213 $all = $this->prevNext->getSelection($this->cacheKey, 'getall')[$this->cacheKey];
214 list ($idLast, $idPrev) = array_reverse(array_keys($all));
215
216 $pos = $this->prevNext->getPositions($this->cacheKey, $idLast);
217 $this->assertTrue((bool) $pos['foundEntry']);
218
219 $this->assertTrue(!isset($pos['next']));
220
221 $this->assertEquals($idPrev, $pos['prev']['id1']);
222 $this->assertTrue(!empty($pos['prev']['data']));
223 }
224
225 /**
226 * Check the neighbors of the last item.
227 *
228 * @dataProvider getFillFunctions
229 */
230 public function testGetPosition_invalid($fillFunction) {
231 call_user_func([$this, $fillFunction]);
232
233 $pos = $this->prevNext->getPositions($this->cacheKey, 99999999);
234 $this->assertFalse((bool) $pos['foundEntry']);
235 $this->assertTrue(!isset($pos['next']));
236 $this->assertTrue(!isset($pos['prev']));
237 }
238
073ba4f0
TO
239 public function testDeleteByCacheKey() {
240 // Add background data
241 $this->prevNext->fillWithArray($this->cacheKeyB, [
242 ['entity_id1' => 100, 'data' => 'Alice'],
243 ['entity_id1' => 150, 'data' => 'Dave'],
244 ]);
245 $this->prevNext->markSelection($this->cacheKeyB, 'select', 100);
246 $this->assertSelections([100], 'get', $this->cacheKeyB);
247 $this->assertSelections([100, 150], 'getall', $this->cacheKeyB);
248
249 // Add some data that we're actually working with.
ab723d18
TO
250 $this->testFillArray();
251
3e9cd8a8 252 $all = $this->assertSelections([100, 400, 200, 300], 'getall', $this->cacheKey);
ab723d18
TO
253
254 list ($id1, $id2, $id3) = array_keys($all);
255 $this->prevNext->markSelection($this->cacheKey, 'select', [$id1, $id3]);
3e9cd8a8 256 $this->assertSelections([$id1, $id3], 'get', $this->cacheKey);
ab723d18
TO
257
258 $this->prevNext->deleteItem(NULL, $this->cacheKey);
3e9cd8a8
TO
259 $this->assertSelections([], 'getall', $this->cacheKey);
260 $this->assertSelections([], 'get', $this->cacheKey);
073ba4f0
TO
261
262 // Ensure background data was untouched.
263 $this->assertSelections([100], 'get', $this->cacheKeyB);
264 $this->assertSelections([100, 150], 'getall', $this->cacheKeyB);
265 }
266
267 public function testDeleteByEntityId() {
268 // Fill two caches
269 $this->prevNext->fillWithArray($this->cacheKey, [
270 ['entity_id1' => 100, 'data' => 'Alice'],
271 ['entity_id1' => 150, 'data' => 'Dave'],
272 ]);
273 $this->prevNext->markSelection($this->cacheKey, 'select', 100);
274 $this->assertSelections([100], 'get', $this->cacheKey);
275 $this->assertSelections([100, 150], 'getall', $this->cacheKey);
276
277 $this->prevNext->fillWithArray($this->cacheKeyB, [
278 ['entity_id1' => 100, 'data' => 'Alice'],
279 ['entity_id1' => 400, 'data' => 'Bob'],
280 ]);
281 $this->prevNext->markSelection($this->cacheKeyB, 'select', [100, 400]);
282 $this->assertSelections([100, 400], 'get', $this->cacheKeyB);
283 $this->assertSelections([100, 400], 'getall', $this->cacheKeyB);
284
285 // Delete
286 $this->prevNext->deleteItem(100);
287 $this->assertSelections([], 'get', $this->cacheKey);
288 $this->assertSelections([150], 'getall', $this->cacheKey);
289 $this->assertSelections([400], 'get', $this->cacheKeyB);
290 $this->assertSelections([400], 'getall', $this->cacheKeyB);
291 }
292
293 public function testDeleteAll() {
294 // Fill two caches
295 $this->prevNext->fillWithArray($this->cacheKey, [
296 ['entity_id1' => 100, 'data' => 'Alice'],
297 ['entity_id1' => 150, 'data' => 'Dave'],
298 ]);
299 $this->prevNext->markSelection($this->cacheKey, 'select', 100);
300 $this->assertSelections([100], 'get', $this->cacheKey);
301 $this->assertSelections([100, 150], 'getall', $this->cacheKey);
302
303 $this->prevNext->fillWithArray($this->cacheKeyB, [
304 ['entity_id1' => 100, 'data' => 'Alice'],
305 ['entity_id1' => 400, 'data' => 'Bob'],
306 ]);
307 $this->prevNext->markSelection($this->cacheKeyB, 'select', [100, 400]);
308 $this->assertSelections([100, 400], 'get', $this->cacheKeyB);
309 $this->assertSelections([100, 400], 'getall', $this->cacheKeyB);
310
311 // Delete
312 $this->prevNext->deleteItem(NULL, NULL);
313 $this->assertSelections([], 'get', $this->cacheKey);
314 $this->assertSelections([], 'getall', $this->cacheKey);
315 $this->assertSelections([], 'get', $this->cacheKeyB);
316 $this->assertSelections([], 'getall', $this->cacheKeyB);
ab723d18
TO
317 }
318
ab723d18
TO
319 /**
320 * Assert that the current cacheKey has a list of selected contact IDs.
321 *
322 * @param array $ids
323 * Contact IDs that should be selected.
39b959db
SL
324 * @param string $action
325 * @param string|NULL $cacheKey
3e9cd8a8
TO
326 * @return array
327 * Contact IDs that were returned by getSelection($cacheKey, $action)
ab723d18 328 */
073ba4f0
TO
329 protected function assertSelections($ids, $action = 'get', $cacheKey = NULL) {
330 if ($cacheKey === NULL) {
331 $cacheKey = $this->cacheKey;
332 }
333 $selected = $this->prevNext->getSelection($cacheKey, $action)[$cacheKey];
8cf1fcac 334 $this->assertEquals($ids, array_keys($selected), 'selected cache not correct for ' . $cacheKey
335 . ' defined keys are ' . $this->cacheKey . 'and ' . $this->cacheKeyB
336 . ' result from getall is ' . print_r($this->prevNext->getSelection($cacheKey, 'getall'), 1)
337 . ' and the prevNext cache is ' . print_r($this->prevNext, TRUE)
338 );
339
ab723d18 340 $this->assertCount(count($ids), $selected);
3e9cd8a8 341 return $selected;
ab723d18
TO
342 }
343
344}