HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/ai.naniguide.com/tests/Unit/UrlServiceMoreTest.php
<?php

namespace Tests\Unit;

use Tests\TestCase;
use App\Model\TrackingDomain;
use DOMDocument;
use DomXpath;
use Exception;
use App\Services\UrlService;

class UrlServiceMoreTest extends TestCase
{
    public const RELATIVE = 'images/sample.png';
    public const ABSOLUTE = '/fake/sample.png';
    public const PUBLIC = 'http://cdn.example.com/sample.png';
    public const PROTOCOL_RELATIVE = '//cdn.example.com/sample.png';
    public const SHARP = '#';

    public const TRACKING_DOMAIN = 'track.example.com';
    public const TRACKING_HOST = 'http://track.example.com/';

    protected function setUp(): void
    {
        parent::setUp();

        // Set base URL
        config()->set('app.url', 'https://example.com');

        // @important: route("named route") does not respect config(app.url)
        //             it uses the actual request url or localhost (in console)
        // So, force it in test
        $this->app['url']->forceRootUrl(config('app.url'));
    }

    public function getHtml()
    {
        return strtr("
            <html>
            <body>
                <img name='relative' src='%relative'>
                <img name='absolute' src='%absolute'>Click me</a>
                <a name='public' href='%public'>
                <a name='protocol_relative' href='%protocol_relative'>Click me</a>
                <img name='sharp' src='%sharp'>
            </body>
            </html>
        ", [
            '%relative' => self::RELATIVE,
            '%absolute' => self::ABSOLUTE,
            '%public' => self::PUBLIC,
            '%protocol_relative' => self::PROTOCOL_RELATIVE,
            '%sharp' => self::SHARP,
        ]);
    }

    public function getElementByAttribute($html, $attribute, $value)
    {
        $document = new DOMDocument();
        $document->encoding = 'utf-8';
        $document->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'), LIBXML_NOWARNING | LIBXML_NOERROR | LIBXML_HTML_NODEFDTD);
        $xpath = new DomXpath($document);
        $elements = $xpath->query("//*[@{$attribute}='$value']");
        if (empty($elements)) {
            throw new Exception("Cannot find element with '$attribute'='$value'");
        }

        if (sizeof($elements) > 1) {
            throw new Exception("There are more than one elements with '$attribute'='$value'");
        }

        return $elements[0];
    }

    public function getElementAttributes($html)
    {
        $map = [
            'img' => 'src',
            'link' => 'href',
            'a' => 'href',
        ];
        $out = [];
        $names = [ 'relative', 'absolute', 'public', 'protocol_relative', 'sharp' ];
        foreach ($names as $name) {
            $element = $this->getElementByAttribute($html, 'name', $name);
            $out[$name] = $element->getAttribute($map[$element->nodeName]);
        }

        /* result looks like
        Array
        (
            [relative] => http://localhost/images/sample.png
            [absolute] => http://localhost/fake/sample.png
            [public] => http://localhost/p/click?url=aHR0cDovL2Nkbi5leGFtcGxlLmNvbS9zYW1wbGUucG5n
            [cdn] => http://localhost/p/click?url=aHR0cDovL2Nkbi5leGFtcGxlLmNvbS9zYW1wbGUucG5n
            [sharp] => #
        )
        */

        return $out;
    }

    public function test_more_test_without_tracking_domain()
    {
        $html = app(UrlService::class)->transformHtmlUrls($this->getHtml(), $msgId = null, $trackingDomain = null);
        $out = $this->getElementAttributes($html);

        // Transformed
        $this->assertEquals($out['relative'], 'https://example.com/images/sample.png');
        $this->assertEquals($out['absolute'], 'https://example.com/fake/sample.png'); // unchanged
        $this->assertEquals($out['public'], 'http://example.com/p/click?url=aHR0cDovL2Nkbi5leGFtcGxlLmNvbS9zYW1wbGUucG5n');
        $this->assertEquals($out['protocol_relative'], 'http://example.com/p/click?url=Ly9jZG4uZXhhbXBsZS5jb20vc2FtcGxlLnBuZw'); // unchanged
        $this->assertEquals($out['sharp'], self::SHARP); // unchanged
    }

    public function test_more_test_with_tracking_domain()
    {
        $domain = new TrackingDomain();
        $domain->name = self::TRACKING_DOMAIN;
        $domain->scheme = 'http';
        $domain->verification_method = TrackingDomain::VERIFICATION_METHOD_HOST;
        $html = app(UrlService::class)->transformHtmlUrls($this->getHtml(), $msgId = null, $domain);

        $out = $this->getElementAttributes($html);

        // Transformed
        $this->assertEquals($out['relative'], 'http://track.example.com/?t=aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZXMvc2FtcGxlLnBuZw');
        $this->assertEquals($out['absolute'], 'http://track.example.com/?t=aHR0cHM6Ly9leGFtcGxlLmNvbS9mYWtlL3NhbXBsZS5wbmc');
        $this->assertEquals($out['public'], 'http://track.example.com/?t=aHR0cDovL2V4YW1wbGUuY29tL3AvY2xpY2s_dXJsPWFIUjBjRG92TDJOa2JpNWxlR0Z0Y0d4bExtTnZiUzl6WVcxd2JHVXVjRzVu');
        $this->assertEquals($out['protocol_relative'], 'http://track.example.com/?t=aHR0cDovL2V4YW1wbGUuY29tL3AvY2xpY2s_dXJsPUx5OWpaRzR1WlhoaGJYQnNaUzVqYjIwdmMyRnRjR3hsTG5CdVp3');
        $this->assertEquals($out['sharp'], self::SHARP); // unchanged
    }
}