From cc6111f9a91c9ddd42f929f13ce30456df6fd27b Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Sun, 23 Jul 2023 23:56:47 -0700 Subject: [PATCH] Civi::url() - Add test-coverage --- tests/phpunit/Civi/Core/UrlTest.php | 84 ++++++++++++++++++++++++++ tests/phpunit/E2E/Core/PathUrlTest.php | 71 ++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 tests/phpunit/Civi/Core/UrlTest.php diff --git a/tests/phpunit/Civi/Core/UrlTest.php b/tests/phpunit/Civi/Core/UrlTest.php new file mode 100644 index 0000000000..35c261f8af --- /dev/null +++ b/tests/phpunit/Civi/Core/UrlTest.php @@ -0,0 +1,84 @@ +assertRegexp(';^[a-z0-9\.\-]+(:\d+)?$;', $parts[2], 'CIVICRM_UF_BASEURL should have domain name and/or port'); + $tmpVars['_SERVER']['HTTP_HOST'] = $parts[2]; + \CRM_Utils_GlobalStack::singleton()->push($tmpVars); + + parent::setUp(); + $this->useTransaction(); + } + + protected function tearDown(): void { + parent::tearDown(); + \CRM_Utils_GlobalStack::singleton()->pop(); + } + + public function testAbsoluteRelative() { + $absolutes = []; + $absolutes['flag'] = Civi::url('backend://civicrm/admin', 'a'); + $absolutes['method'] = Civi::url('backend://civicrm/admin')->setPreferFormat('absolute'); + + $relatives = []; + $relatives['default'] = Civi::url('backend://civicrm/admin'); + $relatives['flag'] = Civi::url('backend://civicrm/admin', 'r'); + $relatives['method'] = Civi::url('backend://civicrm/admin')->setPreferFormat('relative'); + + foreach ($absolutes as $key => $url) { + $this->assertRegExp(';^https?://;', (string) $url, "absolutes[$key] should be absolute URL"); + } + foreach ($relatives as $key => $url) { + $this->assertNotRegExp(';^https?://;', (string) $url, "relatives[$key] should be relative URL"); + } + } + + public function testPath() { + $examples = []; + $examples[] = ['civicrm/ajax/api4', Civi::url('service://civicrm/ajax/api4')]; + $examples[] = ['civicrm/ajax/api4/Contact/get', Civi::url('service://civicrm/ajax/api4')->addPath('Contact/get')]; + $examples[] = ['civicrm/ajax/api4/Contact/get', Civi::url('service://civicrm/ajax/api4')->addPath('Contact')->addPath('get')]; + $examples[] = ['civicrm/new-path', Civi::url('service://civicrm/old-path')->setPath('civicrm/new-path')]; + + foreach ($examples as $key => $example) { + /** @var \Civi\Core\Url $url */ + [$expected, $url] = $example; + $this->assertEquals($expected, $url->getPath()); + $this->assertStringContainsString($expected, (string) $url); + } + } + + public function testQuery() { + $examples = []; + $examples[] = ['reset=1&id=9', Civi::url('frontend://civicrm/profile/view?reset=1&id=9')]; + $examples[] = ['reset=1&id=9', Civi::url('frontend://civicrm/profile/view')->addQuery('reset=1&id=9')]; + $examples[] = ['reset=1&id=9', Civi::url('frontend://civicrm/profile/view')->addQuery(['reset' => 1, 'id' => 9])]; + $examples[] = ['noise=Hello+world%3F', Civi::url('frontend://civicrm/profile/view?noise=Hello+world%3F')]; + $examples[] = ['noise=Hello+world%3F', Civi::url('frontend://civicrm/profile/view')->addQuery(['noise' => 'Hello world?'])]; + $examples[] = ['reset=1&id=9', Civi::url('frontend://civicrm/profile/view?forget=this')->setQuery('reset=1&id=9')]; + $examples[] = ['reset=1&id=9', Civi::url('frontend://civicrm/profile/view?forget=this')->setQuery('reset=1')->addQuery('id=9')]; + + foreach ($examples as $key => $example) { + /** @var \Civi\Core\Url $url */ + [$expected, $url] = $example; + $this->assertEquals($expected, $url->getQuery()); + $this->assertStringContainsString($expected, (string) $url); + } + } + +} diff --git a/tests/phpunit/E2E/Core/PathUrlTest.php b/tests/phpunit/E2E/Core/PathUrlTest.php index 2fd0f4c121..28ce71e83b 100644 --- a/tests/phpunit/E2E/Core/PathUrlTest.php +++ b/tests/phpunit/E2E/Core/PathUrlTest.php @@ -68,6 +68,77 @@ class PathUrlTest extends \CiviEndToEndTestCase { } } + /** + * Get URLs through Civi::url(). + * + * @see \Civi\Core\UrlTest + */ + public function testUrl(): void { + // Make some requests for actual URLs + $this->assertUrlContentRegex(';MIT-LICENSE.txt;', \Civi::url('[civicrm.packages]/jquery/plugins/jquery.timeentry.js', 'a')); + $this->assertUrlContentRegex(';MIT-LICENSE.txt;', \Civi::url('asset://[civicrm.packages]/jquery/plugins/jquery.timeentry.js', 'a')); + $this->assertUrlContentRegex(';Please enter a valid email address;', \Civi::url('assetBuilder://crm-l10n.js?locale=en_US', 'a')); + $this->assertUrlContentRegex(';.module..crmSearchAdmin;', \Civi::url('ext://org.civicrm.search_kit/ang/crmSearchAdmin.module.js', 'a')); + $this->assertUrlContentRegex(';crm-section event_date_time-section;', \Civi::url('frontend://civicrm/event/info?id=1', 'a')); + + // Check for well-formedness of some URLs + $urlPats = []; + switch (CIVICRM_UF) { + case 'Drupal': + case 'Drupal8': + case 'Backdrop': + $urlPats[] = [';/civicrm/event/info\?reset=1&id=9;', \Civi::url('frontend://civicrm/event/info?reset=1')->addQuery('id=9')]; + $urlPats[] = [';/civicrm/admin\?reset=1;', \Civi::url('backend://civicrm/admin')->addQuery(['reset' => 1])]; + break; + + case 'WordPress': + $urlPats[] = [';civiwp=CiviCRM.*civicrm.*event.*info.*reset=1&id=9;', \Civi::url('frontend://civicrm/event/info?reset=1')->addQuery('id=9')]; + $urlPats[] = [';/wp-admin.*civicrm.*admin.*reset=1;', \Civi::url('backend://civicrm/admin?reset=1')]; + break; + + case 'Joomla': + $urlPats[] = [';/index.php\?.*task=civicrm/event/info&reset=1&id=9;', \Civi::url('frontend://civicrm/event/inof?reset=1')->addQuery('id=9')]; + $urlPats[] = [';/administrator/.*task=civicrm/admin/reset=1;', \Civi::url('backend://civicrm/admin')->addQuery('reset=1')]; + break; + + default: + $this->fail('Unrecognized UF: ' . CIVICRM_UF); + } + + $urlPats[] = [';^https?://.*civicrm;', \Civi::url('frontend://civicrm/event/info?reset=1', 'a')]; + $urlPats[] = [';^https://.*civicrm;', \Civi::url('frontend://civicrm/event/info?reset=1', 'as')]; + + // Some test-harnesses have HTTP_HOST. Some don't. It's pre-req for truly relative URLs. + if (!empty($_SERVER['HTTP_HOST'])) { + $urlPats[] = [';^/.*civicrm.*ajax.*api4.*Contact.*get;', \Civi::url('backend://civicrm/ajax/api4/Contact/get', 'r')]; + } + + $this->assertNotEmpty($urlPats); + foreach ($urlPats as $urlPat) { + $this->assertRegExp($urlPat[0], $urlPat[1]); + } + } + + /** + * Check that 'frontend://', 'backend://', and 'current://' have the expected relations. + */ + public function testUrl_FrontBackCurrent(): void { + $front = (string) \Civi::url('frontend://civicrm/profile/view'); + $back = (string) \Civi::url('backend://civicrm/profile/view'); + $current = (string) \Civi::url('current://civicrm/profile/view'); + $this->assertStringContainsString('profile', $front); + $this->assertStringContainsString('profile', $back); + $this->assertStringContainsString('profile', $current); + if (CIVICRM_UF === 'WordPress' || CIVICRM_UF === 'Joomla') { + $this->assertNotEquals($front, $back, "On WordPress/Joomla, some URLs should support frontend+backend flavors."); + } + else { + $this->assertEquals($front, $back, "On Drupal/Backdrop/Standalone, frontend and backend URLs should look the same."); + } + $this->assertEquals($back, $current, "Within E2E tests, current routing style is backend."); + // For purposes of this test, it doesn't matter if "current" is frontend or backend - as long as it's consistent. + } + /** * @param string $expectContentRegex * @param string $url -- 2.25.1