4 * Class CRM_Utils_StringTest
7 class CRM_Utils_StringTest
extends CiviUnitTestCase
{
9 public function setUp() {
13 public function testStripPathChars() {
17 'civicrm' => 'civicrm',
18 'civicrm/dashboard' => 'civicrm/dashboard',
19 'civicrm/contribute/transact' => 'civicrm/contribute/transact',
20 'civicrm/<hack>attempt</hack>' => 'civicrm/_hack_attempt_/hack_',
21 'civicrm dashboard & force = 1,;' => 'civicrm_dashboard___force___1__',
24 foreach ($testSet as $in => $expected) {
25 $out = CRM_Utils_String
::stripPathChars($in);
26 $this->assertEquals($out, $expected, "Output does not match");
30 public function testExtractName() {
33 'full_name' => 'Alan',
34 'first_name' => 'Alan',
37 'full_name' => 'Alan Arkin',
38 'first_name' => 'Alan',
39 'last_name' => 'Arkin',
42 'full_name' => '"Alan Arkin"',
43 'first_name' => 'Alan',
44 'last_name' => 'Arkin',
47 'full_name' => 'Alan A Arkin',
48 'first_name' => 'Alan',
50 'last_name' => 'Arkin',
53 'full_name' => 'Adams, Amy',
54 'first_name' => 'Amy',
55 'last_name' => 'Adams',
58 'full_name' => 'Adams, Amy A',
59 'first_name' => 'Amy',
61 'last_name' => 'Adams',
64 'full_name' => '"Adams, Amy A"',
65 'first_name' => 'Amy',
67 'last_name' => 'Adams',
70 foreach ($cases as $case) {
72 CRM_Utils_String
::extractName($case['full_name'], $actual);
73 $this->assertEquals($actual['first_name'], $case['first_name']);
74 $this->assertEquals(CRM_Utils_Array
::value('last_name', $actual), CRM_Utils_Array
::value('last_name', $case));
75 $this->assertEquals(CRM_Utils_Array
::value('middle_name', $actual), CRM_Utils_Array
::value('middle_name', $case));
79 public function testEllipsify() {
86 foreach ($cases as $input => $expected) {
87 $this->assertEquals($expected, CRM_Utils_String
::ellipsify($input, $maxLen));
89 // test utf-8 string, CRM-18997
90 $input = 'Registro de eventos on-line: Taller: "Onboarding - Cómo integrar exitosamente a los nuevos talentos dentro de su organización - Formación práctica."';
92 $this->assertEquals(TRUE, mb_check_encoding(CRM_Utils_String
::ellipsify($input, $maxLen), 'UTF-8'));
95 public function testRandom() {
96 for ($i = 0; $i < 4; $i++
) {
97 $actual = CRM_Utils_String
::createRandom(4, 'abc');
98 $this->assertEquals(4, strlen($actual));
99 $this->assertRegExp('/^[abc]+$/', $actual);
101 $actual = CRM_Utils_String
::createRandom(6, '12345678');
102 $this->assertEquals(6, strlen($actual));
103 $this->assertRegExp('/^[12345678]+$/', $actual);
110 public function parsePrefixData() {
112 $cases[] = array('administer CiviCRM', NULL, array(NULL, 'administer CiviCRM'));
113 $cases[] = array('administer CiviCRM', 'com_civicrm', array('com_civicrm', 'administer CiviCRM'));
114 $cases[] = array('Drupal:access user profiles', NULL, array('Drupal', 'access user profiles'));
115 $cases[] = array('Joomla:component:perm', NULL, array('Joomla', 'component:perm'));
120 * @dataProvider parsePrefixData
122 * @param $defaultPrefix
125 public function testParsePrefix($input, $defaultPrefix, $expected) {
126 $actual = CRM_Utils_String
::parsePrefix(':', $input, $defaultPrefix);
127 $this->assertEquals($expected, $actual);
133 public function booleanDataProvider() {
134 // array(0 => $input, 1 => $expectedOutput)
136 $cases[] = array(TRUE, TRUE);
137 $cases[] = array(FALSE, FALSE);
138 $cases[] = array(1, TRUE);
139 $cases[] = array(0, FALSE);
140 $cases[] = array('1', TRUE);
141 $cases[] = array('0', FALSE);
142 $cases[] = array(TRUE, TRUE);
143 $cases[] = array(FALSE, FALSE);
144 $cases[] = array('Y', TRUE);
145 $cases[] = array('N', FALSE);
146 $cases[] = array('y', TRUE);
147 $cases[] = array('n', FALSE);
148 $cases[] = array('Yes', TRUE);
149 $cases[] = array('No', FALSE);
150 $cases[] = array('True', TRUE);
151 $cases[] = array('False', FALSE);
152 $cases[] = array('yEs', TRUE);
153 $cases[] = array('nO', FALSE);
154 $cases[] = array('tRuE', TRUE);
155 $cases[] = array('FaLsE', FALSE);
161 * @param bool $expected
162 * * @dataProvider booleanDataProvider
164 public function testStrToBool($input, $expected) {
165 $actual = CRM_Utils_String
::strtobool($input);
166 $this->assertTrue($expected === $actual);
169 public function startEndCases() {
171 $cases[] = array('startsWith', 'foo', '', TRUE);
172 $cases[] = array('startsWith', 'foo', 'f', TRUE);
173 $cases[] = array('startsWith', 'foo', 'fo', TRUE);
174 $cases[] = array('startsWith', 'foo', 'foo', TRUE);
175 $cases[] = array('startsWith', 'foo', 'fooo', FALSE);
176 $cases[] = array('startsWith', 'foo', 'o', FALSE);
177 $cases[] = array('endsWith', 'foo', 'f', FALSE);
178 $cases[] = array('endsWith', 'foo', '', TRUE);
179 $cases[] = array('endsWith', 'foo', 'o', TRUE);
180 $cases[] = array('endsWith', 'foo', 'oo', TRUE);
181 $cases[] = array('endsWith', 'foo', 'foo', TRUE);
182 $cases[] = array('endsWith', 'foo', 'fooo', FALSE);
183 $cases[] = array('endsWith', 'foo*', '*', TRUE);
188 * @param string $func
189 * One of: 'startsWith' or 'endsWith'.
192 * @param $expectedResult
193 * @dataProvider startEndCases
195 public function testStartEndWith($func, $string, $fragment, $expectedResult) {
196 $actualResult = \CRM_Utils_String
::$func($string, $fragment);
197 $this->assertEquals($expectedResult, $actualResult, "Checking $func($string,$fragment)");
200 public function wildcardCases() {
202 $cases[] = array('*', array('foo.bar.1', 'foo.bar.2', 'foo.whiz', 'bang.bang'));
203 $cases[] = array('foo.*', array('foo.bar.1', 'foo.bar.2', 'foo.whiz'));
204 $cases[] = array('foo.bar.*', array('foo.bar.1', 'foo.bar.2'));
205 $cases[] = array(array('foo.bar.*', 'foo.bar.2'), array('foo.bar.1', 'foo.bar.2'));
206 $cases[] = array(array('foo.bar.2', 'foo.w*'), array('foo.bar.2', 'foo.whiz'));
212 * @param $expectedResults
213 * @dataProvider wildcardCases
215 public function testFilterByWildCards($patterns, $expectedResults) {
216 $data = array('foo.bar.1', 'foo.bar.2', 'foo.whiz', 'bang.bang');
218 $actualResults = CRM_Utils_String
::filterByWildcards($patterns, $data);
219 $this->assertEquals($expectedResults, $actualResults);
221 $patterns = (array) $patterns;
222 $patterns[] = 'noise';
224 $actualResults = CRM_Utils_String
::filterByWildcards($patterns, $data, FALSE);
225 $this->assertEquals($expectedResults, $actualResults);
227 $actualResults = CRM_Utils_String
::filterByWildcards($patterns, $data, TRUE);
228 $this->assertEquals(array_merge($expectedResults, array('noise')), $actualResults);
235 * @param string $imageURL
236 * @param book $forceHttps
237 * @param string $expected
239 * @dataProvider simplifyURLProvider
241 public function testSimplifyURL($imageURL, $forceHttps, $expected) {
244 CRM_Utils_String
::simplifyURL($imageURL, $forceHttps)
249 * Used for testNormalizeImageURL above
253 public function simplifyURLProvider() {
254 $config = CRM_Core_Config
::singleton();
255 $urlParts = CRM_Utils_String
::simpleParseUrl($config->userFrameworkBaseURL
);
256 $localDomain = $urlParts['host+port'];
257 if (empty($localDomain)) {
258 throw new \
Exception("Failed to determine local base URL");
260 $externalDomain = 'example.org';
262 // Ensure that $externalDomain really is different from $localDomain
263 if ($externalDomain == $localDomain) {
264 $externalDomain = 'example.net';
268 'prototypical example' => array(
269 "https://$localDomain/sites/default/files/coffee-mug.jpg",
271 '/sites/default/files/coffee-mug.jpg',
273 'external domain with https' => array(
274 "https://$externalDomain/sites/default/files/coffee-mug.jpg",
276 "https://$externalDomain/sites/default/files/coffee-mug.jpg",
278 'external domain with http forced to https' => array(
279 "http://$externalDomain/sites/default/files/coffee-mug.jpg",
281 "https://$externalDomain/sites/default/files/coffee-mug.jpg",
283 'external domain with http not forced' => array(
284 "http://$externalDomain/sites/default/files/coffee-mug.jpg",
286 "http://$externalDomain/sites/default/files/coffee-mug.jpg",
288 'local URL' => array(
289 "/sites/default/files/coffee-mug.jpg",
291 "/sites/default/files/coffee-mug.jpg",
293 'local URL without a forward slash' => array(
294 "sites/default/files/coffee-mug.jpg",
296 "/sites/default/files/coffee-mug.jpg",
298 'empty input' => array(
308 * @param array $expected
310 * @dataProvider parseURLProvider
312 public function testSimpleParseUrl($url, $expected) {
315 CRM_Utils_String
::simpleParseUrl($url)
320 * Used for testSimpleParseUrl above
324 public function parseURLProvider() {
326 "prototypical example" => array(
327 "https://example.com:8000/foo/bar/?id=1#fragment",
329 'host+port' => "example.com:8000",
330 'path+query' => "/foo/bar/?id=1",
333 "default port example" => array(
334 "https://example.com/foo/bar/?id=1#fragment",
336 'host+port' => "example.com",
337 'path+query' => "/foo/bar/?id=1",
347 "path only" => array(
348 "/foo/bar/image.png",
351 'path+query' => "/foo/bar/image.png",
357 public function purifyHTMLProvider() {
359 $tests[] = ['<span onmouseover=alert(0)>HOVER</span>', '<span>HOVER</span>'];
360 $tests[] = ['<a href="https://civicrm.org" target="_blank" class="button-purple">hello</a>', '<a href="https://civicrm.org" target="_blank" class="button-purple" rel="noreferrer noopener">hello</a>'];
365 * Test ouput of purifyHTML
366 * @param string $testString
367 * @param string $expectedString
368 * @dataProvider purifyHTMLProvider
370 public function testPurifyHTML($testString, $expectedString) {
371 $this->assertEquals($expectedString, CRM_Utils_String
::purifyHTML($testString));