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/be.naniguide.com/tests/Unit/TagTranslationServiceTest.php
<?php

namespace Tests\Unit;

use Tests\TestCase;
use App\Services\TagTranslationService;
use App\Library\Contracts\TagResolverInterface;
use App\Model\Subscriber;

class TagTranslationServiceTest extends TestCase
{
    public function test_it_translates_tags_using_resolvers()
    {
        // Resolve via service container
        $service = app(TagTranslationService::class);

        $resolver = new class implements TagResolverInterface {
            public function getResolvedTags(): array
            {
                return [
                    'name' => 'Alice',
                    'email' => '[email protected]',
                ];
            }
        };

        $input = 'Hello {{ name   }}, your email is {{ email }}.';
        $expected = 'Hello Alice, your email is [email protected].';

        $result = $service->translate($input, $resolver);

        $this->assertEquals($expected, $result);
    }

    public function test_it_ignores_missing_tags()
    {
        $service = app(TagTranslationService::class);

        $resolver = new class implements TagResolverInterface {
            public function getResolvedTags(): array
            {
                return ['name' => 'Bob'];
            }
        };

        $input = 'Hi {{ name }}, your age is {{ age }}.';
        $expected = 'Hi Bob, your age is .'; // Twig leaves missing tags blank

        $result = $service->translate($input, $resolver);

        $this->assertEquals($expected, $result);
    }

    public function test_it_combines_multiple_resolvers()
    {
        $service = app(TagTranslationService::class);

        $resolverA = new class implements TagResolverInterface {
            public function getResolvedTags(): array
            {
                return ['name' => 'Charlie'];
            }
        };

        $resolverB = new class implements TagResolverInterface {
            public function getResolvedTags(): array
            {
                return ['city' => 'Paris'];
            }
        };

        $input = 'Hello {{ name }} from {{ city }}!';
        $expected = 'Hello Charlie from Paris!';

        $result = $service->translate($input, $resolverA, $resolverB);

        $this->assertEquals($expected, $result);
    }

    public function test_with_a_domain_object_resolver_also_support_tags_flattening()
    {
        $service = app(TagTranslationService::class);

        $mailList = new \App\Model\MailList([
            'name' => 'Weekly Updates!'
        ]);

        $mailList->uid = '1000000000'; // UID is not fillable, explicitly assign


        $testCases = [
            'Hello "{{ list.name }}"' => 'Hello "Weekly Updates!"',
            'Hello "{{ list_name }}"' => 'Hello "Weekly Updates!"',
            'Hello "{{ LIST_NAME }}"' => 'Hello "Weekly Updates!"',
            'Hello "{{ LIST.NAME }}", My UID is {{ LIST_UID }}"' => 'Hello "Weekly Updates!", My UID is 1000000000"',
            '{{ LIST.NAME }} {{ LIST.UID }} {{ LIST_NAME }} {{ LIST.UID }}' => 'Weekly Updates! 1000000000 Weekly Updates! 1000000000',

            '{{List.Name}} is invalid' => ' is invalid', // empty, no exception thrown
        ];

        foreach ($testCases as $input => $expectedTesult) {
            $result = $service->translate($input, $mailList);
            $this->assertEquals($result, $expectedTesult);
        }
    }

    public function test_advanced_subscriber_tag_resolver()
    {
        // Create a Subscriber mock with intrinsic tags
        $subscriber = new class extends \App\Model\Subscriber {
            public int $id = 123;
            public \App\Model\MailList $mailList;

            public function __construct()
            {
                $this->mailList = new class extends \App\Model\MailList {
                    public string $uid = 'list-uid-456';
                    public \App\Model\Customer $customer;

                    public function __construct()
                    {
                        $this->customer = new class extends \App\Model\Customer {
                            public string $uid = 'customer-uid-789';
                        };
                    }
                };
            }

            public function getResolvedTags(): array
            {
                return [
                    'SUBSCRIBER_UID' => $this->id,
                    'SUBSCRIBER_EMAIL' => '[email protected]',
                ];
            }

            public function generateUnsubscribeFormUrl(?string $messageId, bool $useAbsoluteUrl = true): string
            {
                return $messageId ? "unsubscribe/{$messageId}" : "unsubscribe/default";
            }

            public function generateUpdateProfileUrl(): string
            {
                return "update-profile/{$this->id}";
            }
        };

        $messageId = 'MSG123';

        // Instantiate the advanced resolver using the factory method
        $resolver = \App\Library\AdvancedSubscriberTagResolver::for($subscriber, $messageId);

        $tags = $resolver->getResolvedTags();

        // Assert that intrinsic subscriber tags are preserved
        $this->assertArrayHasKey('SUBSCRIBER_UID', $tags);
        $this->assertArrayHasKey('SUBSCRIBER_EMAIL', $tags);
        $this->assertEquals(123, $tags['SUBSCRIBER_UID']);
        $this->assertEquals('[email protected]', $tags['SUBSCRIBER_EMAIL']);

        // Assert that advanced tags are added
        $this->assertArrayHasKey('unsubscribe_url', $tags);
        $this->assertArrayHasKey('update_profile_url', $tags);
        $this->assertEquals('unsubscribe/MSG123', $tags['unsubscribe_url']);
        $this->assertEquals('update-profile/123', $tags['update_profile_url']);
    }

    public function test_advanced_subscriber_tag_resolver_with_subscriber_fake_object()
    {
        // Create a Subscriber mock with intrinsic tags
        $messageId = 'MSG123';
        $subscriber = Subscriber::fake(
            attributes: [
                'email' => '[email protected]',
            ],
            methods: [
                'generateUnsubscribeFormUrl' => "unsubscribe/",
                'generateUpdateProfileUrl' => "update-profile/",
                'getResolvedTags' => [
                    'SUBSCRIBER_UID' => 123,
                    'SUBSCRIBER_EMAIL' => '[email protected]',
                ]
            ],
        );

        // Instantiate the advanced resolver using the factory method
        $resolver = \App\Library\AdvancedSubscriberTagResolver::for($subscriber, $messageId, $withHost = false);
        $tags = $resolver->getResolvedTags();

        // Assert that intrinsic subscriber tags are preserved
        $this->assertArrayHasKey('SUBSCRIBER_UID', $tags);
        $this->assertArrayHasKey('SUBSCRIBER_EMAIL', $tags);
        $this->assertEquals(123, $tags['SUBSCRIBER_UID']);
        $this->assertEquals('[email protected]', $tags['SUBSCRIBER_EMAIL']);

        // Assert that advanced tags are added
        $this->assertArrayHasKey('unsubscribe_url', $tags);
        $this->assertArrayHasKey('update_profile_url', $tags);
        $this->assertEquals('unsubscribe/', $tags['unsubscribe_url']);
        $this->assertEquals('update-profile/', $tags['update_profile_url']);
        $this->assertEquals('/campaigns/TVNHMTIz/web-view', $tags['web_view_url']);
    }
}