Merge pull request #16629 from WeMoveEU/core-1620
[civicrm-core.git] / tests / phpunit / CRM / Utils / SystemTest.php
1 <?php
2
3
4 /**
5 * Class CRM_Utils_SystemTest
6 * @group headless
7 */
8 class CRM_Utils_SystemTest extends CiviUnitTestCase {
9
10 public function setUp() {
11 parent::setUp();
12 }
13
14 public function testUrlQueryString() {
15 $config = CRM_Core_Config::singleton();
16 $this->assertTrue($config->userSystem instanceof CRM_Utils_System_UnitTests);
17 $expected = '/index.php?q=civicrm/foo/bar&foo=ab&bar=cd%26ef';
18 $actual = CRM_Utils_System::url('civicrm/foo/bar', 'foo=ab&bar=cd%26ef', FALSE, NULL, FALSE);
19 $this->assertEquals($expected, $actual);
20 }
21
22 public function testUrlQueryArray() {
23 $config = CRM_Core_Config::singleton();
24 $this->assertTrue($config->userSystem instanceof CRM_Utils_System_UnitTests);
25 $expected = '/index.php?q=civicrm/foo/bar&foo=ab&bar=cd%26ef';
26 $actual = CRM_Utils_System::url('civicrm/foo/bar', [
27 'foo' => 'ab',
28 'bar' => 'cd&ef',
29 ], FALSE, NULL, FALSE);
30 $this->assertEquals($expected, $actual);
31 }
32
33 public function testEvalUrl() {
34 $this->assertEquals(FALSE, CRM_Utils_System::evalUrl(FALSE));
35 $this->assertEquals('http://example.com/', CRM_Utils_System::evalUrl('http://example.com/'));
36 $this->assertEquals('http://example.com/?cms=UnitTests', CRM_Utils_System::evalUrl('http://example.com/?cms={uf}'));
37 }
38
39 /**
40 * Test the redirect hook.
41 *
42 * @param string $url
43 * @param array $parsedUrl
44 *
45 * @dataProvider getURLs
46 */
47 public function testRedirectHook($url, $parsedUrl) {
48 $this->hookClass->setHook('civicrm_alterRedirect', [$this, 'hook_civicrm_alterRedirect']);
49 try {
50 CRM_Utils_System::redirect($url, [
51 'expected' => $parsedUrl,
52 'original' => $url,
53 ]);
54 }
55 catch (CRM_Core_Exception $e) {
56 $this->assertEquals(ts('hook called'), $e->getMessage());
57 return;
58 }
59 $this->fail('Exception should have been thrown if hook was called');
60 }
61
62 /**
63 * Hook for alterRedirect.
64 *
65 * We do some checks here.
66 *
67 * @param \Psr\Http\Message\UriInterface $urlQuery
68 * @param array $context
69 *
70 * @throws \CRM_Core_Exception
71 */
72 public function hook_civicrm_alterRedirect($urlQuery, $context) {
73 $this->assertEquals(CRM_Utils_Array::value('scheme', $context['expected']), $urlQuery->getScheme());
74 $this->assertEquals(CRM_Utils_Array::value('host', $context['expected']), $urlQuery->getHost());
75 $this->assertEquals(CRM_Utils_Array::value('query', $context['expected']), $urlQuery->getQuery());
76 $this->assertEquals($context['original'], CRM_Utils_Url::unparseUrl($urlQuery));
77
78 throw new CRM_Core_Exception(ts('hook called'));
79 }
80
81 /**
82 * Get urls for testing.
83 *
84 * @return array
85 */
86 public function getURLs() {
87 return [
88 [
89 'https://example.com?ab=cd',
90 [
91 'scheme' => 'https',
92 'host' => 'example.com',
93 'query' => 'ab=cd',
94 ],
95 ],
96 [
97 'http://myuser:mypass@foo.bar:123/whiz?a=b&c=d',
98 [
99 'scheme' => 'http',
100 'host' => 'foo.bar',
101 'port' => 123,
102 'user' => 'myuser',
103 'pass' => 'mypass',
104 'path' => '/whiz',
105 'query' => 'a=b&c=d',
106 ],
107 ],
108 [
109 '/foo/bar',
110 [
111 'path' => '/foo/bar',
112 ],
113 ],
114 ];
115 }
116
117 /**
118 * Test extern url.
119 */
120 public function testExternUrl() {
121 $siteKey = mt_rand();
122 $apiKey = mt_rand();
123 $restUrl = CRM_Utils_System::externUrl('extern/rest', "entity=Contact&action=get&key=$siteKey&api_key=$apiKey");
124 $this->assertContains('extern/rest.php', $restUrl);
125 $this->assertContains('?', $restUrl);
126 $this->assertContains('entity=Contact', $restUrl);
127 $this->assertContains('action=get', $restUrl);
128 $this->assertContains("key=$siteKey", $restUrl);
129 $this->assertContains("api_key=$apiKey", $restUrl);
130 }
131
132 /**
133 * Test the alterExternUrl hook.
134 *
135 * @param string $path
136 * @param array $expected
137 *
138 * @dataProvider getExternURLs
139 */
140 public function testAlterExternUrlHook($path, $expected) {
141 Civi::dispatcher()->addListener('hook_civicrm_alterExternUrl', [$this, 'hook_civicrm_alterExternUrl']);
142 $externUrl = CRM_Utils_System::externUrl($path, $expected['query']);
143 $this->assertContains('path/altered/by/hook', $externUrl, 'Hook failed to alter URL path');
144 $this->assertContains($expected['query'] . '&thisWas=alteredByHook', $externUrl, 'Hook failed to alter URL query');
145 }
146
147 /**
148 * Hook for alterExternUrl.
149 *
150 * @param \Civi\Core\Event\GenericHookEvent $event
151 * @param string $hookName
152 */
153 public function hook_civicrm_alterExternUrl(\Civi\Core\Event\GenericHookEvent $event, $hookName) {
154 $this->assertEquals('hook_civicrm_alterExternUrl', $hookName);
155 $this->assertTrue($event->hasField('url'));
156 $this->assertTrue($event->hasField('path'));
157 $this->assertTrue($event->hasField('query'));
158 $this->assertTrue($event->hasField('fragment'));
159 $this->assertTrue($event->hasField('absolute'));
160 $this->assertTrue($event->hasField('isSSL'));
161 $event->url = $event->url->withPath('path/altered/by/hook');
162 $event->url = $event->url->withQuery($event->query . '&thisWas=alteredByHook');
163 }
164
165 /**
166 * Get extern url params for testing.
167 *
168 * @return array
169 */
170 public function getExternURLs() {
171 return [
172 [
173 'extern/url',
174 [
175 'path' => 'extern/url',
176 'query' => 'u=1&qid=1',
177 ],
178 ],
179 [
180 'extern/open',
181 [
182 'path' => 'extern/open',
183 'query' => 'q=1',
184 ],
185 ],
186 ];
187 }
188
189 /**
190 * Demonstrate the, um, "flexibility" of isNull
191 */
192 public function testIsNull() {
193 $this->assertTrue(CRM_Utils_System::isNull(NULL));
194 $this->assertTrue(CRM_Utils_System::isNull(''));
195 $this->assertTrue(CRM_Utils_System::isNull('null'));
196 // Not sure how to test this one because phpunit itself throws an error.
197 // $this->assertTrue(CRM_Utils_System::isNull($someUnsetVariable));
198
199 // but...
200 $this->assertFalse(CRM_Utils_System::isNull('NULL'));
201 $this->assertFalse(CRM_Utils_System::isNull('Null'));
202
203 // probably ok?
204 $this->assertTrue(CRM_Utils_System::isNull([]));
205
206 // ok
207 $this->assertFalse(CRM_Utils_System::isNull(0));
208
209 // sure
210 $arr = [
211 1 => NULL,
212 ];
213 $this->assertTrue(CRM_Utils_System::isNull($arr[1]));
214 $this->assertTrue(CRM_Utils_System::isNull($arr));
215
216 // but then a little confusing
217 $arr = [
218 'IN' => NULL,
219 ];
220 $this->assertFalse(CRM_Utils_System::isNull($arr));
221
222 // now just guessing
223 $obj = new StdClass();
224 $this->assertFalse(CRM_Utils_System::isNull($obj));
225 $obj->anything = NULL;
226 $this->assertFalse(CRM_Utils_System::isNull($obj));
227
228 // this is ok
229 $arr = [
230 1 => [
231 'foo' => 'bar',
232 ],
233 2 => [
234 'a' => NULL,
235 ],
236 ];
237 $this->assertFalse(CRM_Utils_System::isNull($arr));
238
239 $arr = [
240 1 => $obj,
241 ];
242 $this->assertFalse(CRM_Utils_System::isNull($arr));
243
244 // sure
245 $arr = [
246 1 => NULL,
247 2 => '',
248 3 => 'null',
249 ];
250 $this->assertTrue(CRM_Utils_System::isNull($arr));
251 }
252
253 /**
254 * Test that flushing cache clears the asset cache.
255 */
256 public function testFlushCacheClearsAssetCache() {
257 // We need to get the file path for the folder and there isn't a public
258 // method to get it, so create a file in the folder using public methods,
259 // then get the path from that, then flush the cache, then check if the
260 // folder is empty.
261 \Civi::dispatcher()->addListener('hook_civicrm_buildAsset', array($this, 'flushCacheClearsAssetCache_buildAsset'));
262 $fakeFile = \Civi::service("asset_builder")->getPath('fakeFile.json');
263
264 CRM_Utils_System::flushCache();
265
266 $fileList = scandir(dirname($fakeFile));
267 // count should be 2, just the standard . and ..
268 $this->assertCount(2, $fileList);
269 }
270
271 /**
272 * Implementation of a hook for civicrm_buildAsset() for testFlushCacheClearsAssetCache.
273 * Awkward wording of above sentence is because phpcs is bugging me about it.
274 * @param \Civi\Core\Event\GenericHookEvent $e
275 */
276 public function flushCacheClearsAssetCache_buildAsset(\Civi\Core\Event\GenericHookEvent $e) {
277 if ($e->asset === 'fakeFile.json') {
278 $e->mimeType = 'application/json';
279 $e->content = '{}';
280 }
281 }
282
283 }