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/Feature/TemplateModelFeatureTest.php
<?php

/**
 * Template model feature tests.
 */

uses(Tests\TestCase::class, Illuminate\Foundation\Testing\DatabaseTransactions::class)
    ->group('applyTemplateFrom');

use App\Model\Template;

test('template model accepts content attributes', function () {
    $template = new Template([
        'name' => 'Welcome Email',
        'content' => '<html><body><h1>Welcome!</h1></body></html>',
        'theme' => 'default',
    ]);

    expect($template->name)->toBe('Welcome Email');
    expect($template->content)->toContain('<h1>Welcome!</h1>');
    expect($template->theme)->toBe('default');
});

test('template has uid in fillable', function () {
    $template = new Template();
    $fillable = $template->getFillable();

    expect($fillable)->toContain('name');
    expect($fillable)->toContain('content');
});

test('applyTemplateFrom copies theme + json + content but not name', function () {
    $source = Template::factory()->create([
        'theme' => 'extended',
        'name' => 'Source',
        'content' => '<html><body>SOURCE-MARKER</body></html>',
        'json' => '{"name":"PageElement","template":"Page","blocks":[{"name":"hero"}],"formats":{"background_color":"#FF0000"}}',
    ]);
    $target = Template::factory()->create([
        'theme' => 'default',
        'name' => 'Target',
        'content' => '<html><body>ORIGINAL</body></html>',
        'json' => Template::DEFAULT_BUILDER_JSON,
    ]);

    // Source has no thumbnail on disk — the copy must no-op cleanly rather
    // than throw. This is the path the "Change Theme" flow hits whenever the
    // source template was never rendered to disk.
    $target->applyTemplateFrom($source);

    $fresh = Template::find($target->id);
    expect($fresh->theme)->toBe('extended');
    expect($fresh->content)->toContain('SOURCE-MARKER');
    expect($fresh->json)->toContain('hero');
    expect($fresh->name)->toBe('Target'); // name must NOT be overwritten
});

test('applyTemplateFrom copies thumbnail file when source has one', function () {
    $source = Template::factory()->create(['name' => 'Source']);
    $target = Template::factory()->create(['name' => 'Target']);

    // Attach a fake 1×1 PNG to the source template via updateThumbnailFromPath,
    // then swap → the target must end up with the same bytes under its own
    // thumb path.
    $pngBytes = base64_decode(
        'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='
    );
    $tmp = tempnam(sys_get_temp_dir(), 'thumb_src_');
    file_put_contents($tmp, $pngBytes);

    try {
        $source->updateThumbnailFromPath($tmp);
        $target->applyTemplateFrom($source);
    } finally {
        if (file_exists($tmp)) @unlink($tmp);
    }

    $storage = app(\App\Library\Storage\StorageInterface::class);
    $targetAsset = \App\Library\Storage\AssetPath::from($target->getThumbPath());
    expect($storage->fileExists($targetAsset))->toBeTrue();
    expect($storage->getFileContent($targetAsset))->toBe($pngBytes);
});

test('getThumbUrl appends ?v=<updated_at> cache-buster when thumb exists', function () {
    $template = Template::factory()->create();

    $pngBytes = base64_decode(
        'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='
    );
    $tmp = tempnam(sys_get_temp_dir(), 'thumb_cb_');
    file_put_contents($tmp, $pngBytes);

    try {
        $template->updateThumbnailFromPath($tmp);
    } finally {
        if (file_exists($tmp)) @unlink($tmp);
    }

    $url = $template->getThumbUrl();
    expect($url)->toContain('?v=');
    // Version must match the model's updated_at timestamp so the URL changes
    // whenever Change Theme re-saves the record (which bumps updated_at).
    expect($url)->toContain('v=' . $template->updated_at->timestamp);
});

test('copyThumbnailFrom no-ops when source has no thumbnail on disk', function () {
    $source = Template::factory()->create(['name' => 'NoThumb']);
    $target = Template::factory()->create(['name' => 'Target']);

    // Must not throw — exercises the early-return guard inside copyThumbnailFrom.
    $target->copyThumbnailFrom($source);

    $storage = app(\App\Library\Storage\StorageInterface::class);
    $targetAsset = \App\Library\Storage\AssetPath::from($target->getThumbPath());
    expect($storage->fileExists($targetAsset))->toBeFalse();
});