Merge pull request #17253 from mattwire/utf8convertblocksize
[civicrm-core.git] / tests / phpunit / CRM / Core / BAO / NavigationTest.php
CommitLineData
31cb1898 1<?php
31cb1898
AN
2
3/**
4 * Class CRM_Core_BAO_NavigationTest.
acb109b7 5 * @group headless
31cb1898
AN
6 */
7class CRM_Core_BAO_NavigationTest extends CiviUnitTestCase {
8
9 /**
10 * Set up data for the test run.
11 *
12 * Here we ensure we are starting from a default report navigation.
13 */
14 public function setUp() {
15 parent::setUp();
412b762a 16 CRM_Core_BAO_Navigation::rebuildReportsNavigation(CRM_Core_Config::domainID());
31cb1898
AN
17 }
18
19 /**
20 * Test that a missing report menu link is added by rebuildReportsNavigation.
21 */
22 public function testCreateMissingReportMenuItemLink() {
23 $reportCount = $this->getCountReportInstances();
51704c4d 24 CRM_Core_DAO::executeQuery("DELETE FROM civicrm_navigation WHERE url LIKE 'civicrm/report/instance/1?reset=1%'");
31cb1898 25 $this->assertEquals($reportCount - 1, $this->getCountReportInstances());
412b762a 26 CRM_Core_BAO_Navigation::rebuildReportsNavigation(CRM_Core_Config::domainID());
31cb1898
AN
27
28 $this->assertEquals($reportCount, $this->getCountReportInstances());
29 $url = 'civicrm/report/instance/1';
30 $url_params = 'reset=1';
31 $new_nav = CRM_Core_BAO_Navigation::getNavItemByUrl($url, $url_params);
32 $this->assertObjectHasAttribute('id', $new_nav);
33 $this->assertNotNull($new_nav->id);
34 }
35
51704c4d 36 /**
37 * Test that a link with output=criteria at the end is not duplicated.
38 */
39 public function testNoDuplicateReportMenuItemLink() {
40 CRM_Core_BAO_Navigation::rebuildReportsNavigation(CRM_Core_Config::domainID());
41 $reportCount = $this->getCountReportInstances();
42 CRM_Core_DAO::executeQuery("
43 UPDATE civicrm_navigation
44 SET url = CONCAT(url, '&output=critieria')
45 WHERE url LIKE 'civicrm/report/instance/%?reset=1'");
46 $this->assertEquals($reportCount, $this->getCountReportInstances());
47 CRM_Core_BAO_Navigation::rebuildReportsNavigation(CRM_Core_Config::domainID());
48
49 $this->assertEquals($reportCount, $this->getCountReportInstances());
50 }
51
dfbeefd8 52 /**
53 * Test that All reports link is not stolen.
54 *
55 * There are 2 All reports links by default. What we DON'T want to see is them
56 * both winding up under the Reports menu - since they already exist they should be unchanged
57 * by rebuilding reports.
58 */
59 public function testNoDuplicateAllReportsLink() {
9099cab3 60 $existing_links = $this->callAPISuccess('Navigation', 'get', ['label' => 'All Reports', 'sequential' => 1]);
dfbeefd8 61 $this->assertNotEquals($existing_links['values'][0]['parent_id'], $existing_links['values'][1]['parent_id']);
62 CRM_Core_BAO_Navigation::rebuildReportsNavigation(CRM_Core_Config::domainID());
9099cab3 63 $new_links = $this->callAPISuccess('Navigation', 'get', ['label' => 'All Reports', 'sequential' => 1]);
dfbeefd8 64 $this->assertEquals($existing_links['values'][0]['parent_id'], $new_links['values'][0]['parent_id']);
65 $this->assertEquals($existing_links['values'][1]['parent_id'], $new_links['values'][1]['parent_id']);
66 }
67
31cb1898 68 /**
0087242f 69 * Test that an existing report link is rebuilt under it's parent.
31cb1898
AN
70 *
71 * Function tests CRM_Core_BAO_Navigation::rebuildReportsNavigation.
72 */
73 public function testUpdateExistingReportMenuLink() {
74 $url = 'civicrm/report/instance/1';
75 $url_params = 'reset=1';
76 $existing_nav = CRM_Core_BAO_Navigation::getNavItemByUrl($url, $url_params);
51704c4d 77
31cb1898
AN
78 $this->assertNotEquals(FALSE, $existing_nav);
79 $existing_nav->parent_id = 1;
80 $existing_nav->save();
412b762a 81 CRM_Core_BAO_Navigation::rebuildReportsNavigation(CRM_Core_Config::domainID());
31cb1898
AN
82 $parent_url = 'civicrm/report/list';
83 $parent_url_params = 'compid=99&reset=1';
0087242f 84 $reportsMenu = CRM_Core_BAO_Navigation::createOrUpdateTopLevelReportsNavItem(CRM_Core_Config::domainID());
85 $parent_nav = CRM_Core_BAO_Navigation::getNavItemByUrl($parent_url, $parent_url_params, $reportsMenu->id);
31cb1898
AN
86 $this->assertNotEquals($parent_nav->id, 1);
87 $changed_existing_nav = new CRM_Core_BAO_Navigation();
88 $changed_existing_nav->id = $existing_nav->id;
89 $changed_existing_nav->find(TRUE);
90 $this->assertEquals($changed_existing_nav->parent_id, $parent_nav->id);
91 }
92
31cb1898
AN
93 /**
94 * Test that a navigation item can be retrieved by it's url.
95 */
96 public function testGetNavItemByUrl() {
97 $random_string = substr(sha1(rand()), 0, 7);
98 $name = "Test Menu Link {$random_string}";
99 $url = "civicrm/test/{$random_string}";
100 $url_params = "reset=1";
9099cab3 101 $params = [
31cb1898
AN
102 'name' => $name,
103 'label' => ts($name),
104 'url' => "{$url}?{$url_params}",
105 'parent_id' => NULL,
106 'is_active' => TRUE,
9099cab3 107 'permission' => [
31cb1898 108 'access CiviCRM',
9099cab3
CW
109 ],
110 ];
31cb1898
AN
111 CRM_Core_BAO_Navigation::add($params);
112 $new_nav = CRM_Core_BAO_Navigation::getNavItemByUrl($url, $url_params);
113 $this->assertObjectHasAttribute('id', $new_nav);
114 $this->assertNotNull($new_nav->id);
115 $new_nav->delete();
116 }
117
51704c4d 118 /**
119 * Test that a navigation item can be retrieved by it's url with a wildcard.
120 *
121 * We want to be able to get a report url with OR without the output=criteria since
122 * that is part of the navigation but not the instance.
123 */
124 public function testGetNavItemByUrlWildcard() {
125 $random_string = substr(sha1(rand()), 0, 7);
126 $name = "Test Menu Link {$random_string}";
127 $url = "civicrm/test/{$random_string}";
128 $url_params = "reset=1&output=criteria";
9099cab3 129 $params = [
51704c4d 130 'name' => $name,
131 'label' => ts($name),
132 'url' => "{$url}?{$url_params}",
133 'parent_id' => NULL,
134 'is_active' => TRUE,
9099cab3 135 'permission' => [
51704c4d 136 'access CiviCRM',
9099cab3
CW
137 ],
138 ];
51704c4d 139 CRM_Core_BAO_Navigation::add($params);
140 $new_nav = CRM_Core_BAO_Navigation::getNavItemByUrl($url, 'reset=1%');
141 $this->assertObjectHasAttribute('id', $new_nav);
142 $this->assertNotNull($new_nav->id);
143 $new_nav->delete();
144 }
145
31cb1898
AN
146 /**
147 * Get a count of report instances.
148 *
149 * @return int
150 */
151 protected function getCountReportInstances() {
152 return CRM_Core_DAO::singleValueQuery(
153 "SELECT count(*) FROM civicrm_navigation WHERE url LIKE 'civicrm/report/instance/%'");
154 }
155
dfbeefd8 156 /**
157 * Get a count of navigation items that match the url.
158 * @param string $url
159 *
160 * @return int
161 */
162 protected function getCountURL($url) {
163 return CRM_Core_DAO::singleValueQuery(
164 "SELECT count(*) FROM civicrm_navigation WHERE url ='{$url}'");
165 }
166
b774b065
TO
167 /**
168 * Run fixNavigationMenu() on a menu which already has navIDs
169 * everywhere. They should be unchanged.
170 */
171 public function testFixNavigationMenu_preserveIDs() {
9099cab3
CW
172 $input[10] = [
173 'attributes' => [
b774b065
TO
174 'label' => 'Custom Menu Entry',
175 'parentID' => NULL,
176 'navID' => 10,
177 'active' => 1,
9099cab3
CW
178 ],
179 'child' => [
180 '11' => [
181 'attributes' => [
b774b065
TO
182 'label' => 'Custom Child Menu',
183 'parentID' => 10,
184 'navID' => 11,
9099cab3 185 ],
b774b065 186 'child' => NULL,
9099cab3
CW
187 ],
188 ],
189 ];
b774b065
TO
190
191 $output = $input;
192 CRM_Core_BAO_Navigation::fixNavigationMenu($output);
193
194 $this->assertEquals(NULL, $output[10]['attributes']['parentID']);
195 $this->assertEquals(10, $output[10]['attributes']['navID']);
196 $this->assertEquals(10, $output[10]['child'][11]['attributes']['parentID']);
197 $this->assertEquals(11, $output[10]['child'][11]['attributes']['navID']);
198 }
199
200 /**
201 * Run fixNavigationMenu() on a menu which is missing some navIDs. They
202 * should be filled in, and others should be preserved.
203 */
204 public function testFixNavigationMenu_inferIDs() {
9099cab3
CW
205 $input[10] = [
206 'attributes' => [
b774b065
TO
207 'label' => 'Custom Menu Entry',
208 'parentID' => NULL,
209 'navID' => 10,
210 'active' => 1,
9099cab3
CW
211 ],
212 'child' => [
213 '0' => [
214 'attributes' => [
b774b065 215 'label' => 'Custom Child Menu',
9099cab3 216 ],
b774b065 217 'child' => NULL,
9099cab3
CW
218 ],
219 '100' => [
220 'attributes' => [
b774b065
TO
221 'label' => 'Custom Child Menu 2',
222 'navID' => 100,
9099cab3 223 ],
b774b065 224 'child' => NULL,
9099cab3
CW
225 ],
226 ],
227 ];
b774b065
TO
228
229 $output = $input;
230 CRM_Core_BAO_Navigation::fixNavigationMenu($output);
231
232 $this->assertEquals('Custom Menu Entry', $output[10]['attributes']['label']);
233 $this->assertEquals(NULL, $output[10]['attributes']['parentID']);
234 $this->assertEquals(10, $output[10]['attributes']['navID']);
235
236 $this->assertEquals('Custom Child Menu', $output[10]['child'][101]['attributes']['label']);
237 $this->assertEquals(10, $output[10]['child'][101]['attributes']['parentID']);
238 $this->assertEquals(101, $output[10]['child'][101]['attributes']['navID']);
239
240 $this->assertEquals('Custom Child Menu 2', $output[10]['child'][100]['attributes']['label']);
241 $this->assertEquals(10, $output[10]['child'][100]['attributes']['parentID']);
242 $this->assertEquals(100, $output[10]['child'][100]['attributes']['navID']);
243 }
244
245 public function testFixNavigationMenu_inferIDs_deep() {
9099cab3
CW
246 $input[10] = [
247 'attributes' => [
b774b065
TO
248 'label' => 'Custom Menu Entry',
249 'parentID' => NULL,
250 'navID' => 10,
251 'active' => 1,
9099cab3
CW
252 ],
253 'child' => [
254 '0' => [
255 'attributes' => [
b774b065 256 'label' => 'Custom Child Menu',
9099cab3
CW
257 ],
258 'child' => [
259 '100' => [
260 'attributes' => [
b774b065
TO
261 'label' => 'Custom Child Menu 2',
262 'navID' => 100,
9099cab3 263 ],
b774b065 264 'child' => NULL,
9099cab3
CW
265 ],
266 ],
267 ],
268 ],
269 ];
b774b065
TO
270
271 $output = $input;
272 CRM_Core_BAO_Navigation::fixNavigationMenu($output);
273
274 $this->assertEquals('Custom Menu Entry', $output[10]['attributes']['label']);
275 $this->assertEquals(NULL, $output[10]['attributes']['parentID']);
276 $this->assertEquals(10, $output[10]['attributes']['navID']);
277
278 $this->assertEquals('Custom Child Menu', $output[10]['child'][101]['attributes']['label']);
279 $this->assertEquals(10, $output[10]['child'][101]['attributes']['parentID']);
280 $this->assertEquals(101, $output[10]['child'][101]['attributes']['navID']);
281
282 $this->assertEquals('Custom Child Menu 2', $output[10]['child'][101]['child'][100]['attributes']['label']);
283 $this->assertEquals(101, $output[10]['child'][101]['child'][100]['attributes']['parentID']);
284 $this->assertEquals(100, $output[10]['child'][101]['child'][100]['attributes']['navID']);
285 }
286
a9b5d172
CW
287 /**
288 * Tests that permissions and component status are checked with the correct operator.
289 */
290 public function testCheckPermissions() {
291 $menuItem = [
292 'permission' => 'access CiviCRM, access CiviContribute',
39b959db 293 'operator' => 'AND',
a9b5d172
CW
294 ];
295 CRM_Core_BAO_ConfigSetting::enableComponent('CiviContribute');
296 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'access CiviContribute'];
297 $this->assertTrue(CRM_Core_BAO_Navigation::checkPermission($menuItem));
298
299 CRM_Core_BAO_ConfigSetting::disableComponent('CiviContribute');
300 $this->assertFalse(CRM_Core_BAO_Navigation::checkPermission($menuItem));
301
302 CRM_Core_BAO_ConfigSetting::enableComponent('CiviContribute');
303 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviContribute'];
304 $this->assertFalse(CRM_Core_BAO_Navigation::checkPermission($menuItem));
305
306 $menuItem['operator'] = 'OR';
307 $this->assertTrue(CRM_Core_BAO_Navigation::checkPermission($menuItem));
308
309 CRM_Core_BAO_ConfigSetting::disableComponent('CiviContribute');
310 $this->assertFalse(CRM_Core_BAO_Navigation::checkPermission($menuItem));
d47b93bf
CW
311
312 CRM_Core_BAO_ConfigSetting::enableComponent('CiviMail');
313 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviMail', 'delete in CiviMail'];
314 $menuItem = [
315 'permission' => 'access CiviMail, delete in CiviMail',
316 'operator' => 'AND',
317 ];
318 $this->assertTrue(CRM_Core_BAO_Navigation::checkPermission($menuItem));
319 $menuItem['operator'] = 'OR';
320 $this->assertTrue(CRM_Core_BAO_Navigation::checkPermission($menuItem));
321 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['delete in CiviMail'];
322 $this->assertTrue(CRM_Core_BAO_Navigation::checkPermission($menuItem));
323 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM'];
324 $this->assertFalse(CRM_Core_BAO_Navigation::checkPermission($menuItem));
325 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviMail', 'delete in CiviMail'];
326 CRM_Core_BAO_ConfigSetting::disableComponent('CiviMail');
327 $this->assertFalse(CRM_Core_BAO_Navigation::checkPermission($menuItem));
a9b5d172
CW
328 }
329
31cb1898 330}