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

/**
 * EmailCustomHtmlTest — verifies the "paste custom HTML" content flow.
 *
 * Covers the Option-1 design: uploaded HTML is stored in a Template row with
 * source='uploaded'. The send pipeline (getBaseHtmlContent) is shared with
 * builder templates; only the edit UX differs.
 */

use App\Model\Campaign;
use App\Model\Contact;
use App\Model\Customer;
use App\Model\Email;
use App\Model\MailList;
use App\Model\Template;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;

uses(TestCase::class);

afterEach(function () {
    $customerIds = DB::table('customers')->where('uid', 'like', 'custhtml_%')->pluck('id');

    $campaignIds = DB::table('campaigns')->whereIn('customer_id', $customerIds)->pluck('id');
    DB::table('campaigns_lists_segments')->whereIn('campaign_id', $campaignIds)->delete();
    DB::table('campaigns')->whereIn('id', $campaignIds)->delete();

    DB::table('emails')->whereIn('customer_id', $customerIds)->delete();
    DB::table('mail_lists')->where('uid', 'like', 'listhtml_%')->delete();
    DB::table('templates')->where('uid', 'like', 'tplhtml_%')->delete();
    DB::table('templates')->where('name', 'like', 'Custom HTML Test %')->delete();
    DB::table('customers')->whereIn('id', $customerIds)->delete();
    DB::table('contacts')->where('uid', 'like', 'contacthtml_%')->delete();
});

function customHtmlFixture(): array
{
    $contact = Contact::forceCreate([
        'uid'        => uniqid('contacthtml_'),
        'first_name' => 'HTML',
        'last_name'  => 'User',
        'email'      => uniqid() . '@custom-html-test.invalid',
    ]);
    $customer = Customer::forceCreate([
        'uid'        => uniqid('custhtml_'),
        'contact_id' => $contact->id,
        'status'     => 'active',
        'timezone'   => 'UTC',
    ]);

    $list = MailList::forceCreate([
        'uid'         => uniqid('listhtml_'),
        'name'        => 'Custom HTML List',
        'customer_id' => $customer->id,
        'from_email'  => '[email protected]',
        'from_name'   => 'HTML Sender',
    ]);

    $builderTemplate = Template::forceCreate([
        'uid'     => uniqid('tplhtml_'),
        'name'    => 'Builder Template',
        'content' => '<html><body><p>Builder content</p></body></html>',
        'json'    => Template::DEFAULT_BUILDER_JSON,
        'source'  => Template::SOURCE_BUILDER,
    ]);

    $thumbDir = storage_path('app/public/templates/thumb');
    if (!is_dir($thumbDir)) {
        mkdir($thumbDir, 0755, true);
    }
    file_put_contents($thumbDir . '/' . $builderTemplate->uid . '.jpg', '');

    return compact('customer', 'list', 'builderTemplate');
}

function newCampaignForHtml(Customer $customer, MailList $list): Campaign
{
    $campaign = $customer->local()->newDefaultCampaign();
    $campaign->saveFromArray(['type' => Email::TYPE_REGULAR]);
    $campaign->subject    = 'HTML Test';
    $campaign->from_email = '[email protected]';
    $campaign->from_name  = 'Sender';
    $campaign->reply_to   = '[email protected]';
    $campaign->save();

    $campaign->addListSegment($list, null);
    $campaign->default_mail_list_id = $list->id;
    $campaign->save();

    return $campaign->fresh(['email']);
}

// ─── Tests ────────────────────────────────────────────────────────────────────

test('Template::SOURCE_* constants exist with expected values', function () {
    expect(Template::SOURCE_BUILDER)->toBe('builder');
    expect(Template::SOURCE_UPLOADED)->toBe('uploaded');
});

test('source is included in Template fillable', function () {
    expect((new Template())->getFillable())->toContain('source');
});

test('Template::makeUploaded creates template with source=uploaded and non-empty json', function () {
    $html     = '<html><body><p>Hello Uploaded</p></body></html>';
    $template = Template::makeUploaded('Custom HTML Test Make', $html);

    expect($template->source)->toBe(Template::SOURCE_UPLOADED);
    expect($template->content)->toBe($html);
    expect($template->name)->toBe('Custom HTML Test Make');
    expect($template->json)->not->toBeNull()->not->toBe('');
    expect($template->isUploaded())->toBeTrue();
});

test('setCustomHtml creates uploaded template and assigns customer_id', function () {
    ['customer' => $customer, 'list' => $list] = customHtmlFixture();

    $campaign = newCampaignForHtml($customer, $list);
    $email    = $campaign->email;

    $html = '<html><body><p>Hello From Paste</p></body></html>';
    $email->setCustomHtml($html, 'Custom HTML Test Paste');

    $email->refresh();
    expect($email->template)->not->toBeNull();
    expect($email->template->source)->toBe(Template::SOURCE_UPLOADED);
    expect($email->template->content)->toBe($html);
    expect($email->isCustomHtml())->toBeTrue();
});

test('setCustomHtml on email with builder template cleans up old template', function () {
    ['customer' => $customer, 'list' => $list, 'builderTemplate' => $builder] = customHtmlFixture();

    $campaign = newCampaignForHtml($customer, $list);
    $email    = $campaign->email;

    $email->setTemplate($builder, 'Custom HTML Test Original');
    $email->refresh();
    $firstTemplateId = $email->template_id;
    expect($firstTemplateId)->not->toBeNull();

    $email->setCustomHtml('<html><body>Replaced</body></html>', 'Custom HTML Test Replacement');
    $email->refresh();

    expect($email->template_id)->not->toBe($firstTemplateId);
    expect(DB::table('templates')->where('id', $firstTemplateId)->exists())->toBeFalse();
    expect($email->template->source)->toBe(Template::SOURCE_UPLOADED);
});

test('getBaseHtmlContent runs full pipeline on uploaded email', function () {
    ['customer' => $customer, 'list' => $list] = customHtmlFixture();

    $campaign = newCampaignForHtml($customer, $list);
    $email    = $campaign->email;

    $email->preheader = 'Sneak peek copy';
    $email->save();
    $email->setCustomHtml('<html><body><p>Pipeline test</p></body></html>', 'Custom HTML Test Pipeline');
    $email->refresh();

    $output = $email->getBaseHtmlContent();

    expect($output)->toContain('<!DOCTYPE');
    expect($output)->toContain('Sneak peek copy');
    expect($output)->toContain('Pipeline test');
});

test('Email::copy on uploaded email creates independent uploaded template', function () {
    ['customer' => $customer, 'list' => $list] = customHtmlFixture();

    $campaign = newCampaignForHtml($customer, $list);
    $email    = $campaign->email;

    $html = '<html><body><p>Original Upload</p></body></html>';
    $email->setCustomHtml($html, 'Custom HTML Test Copy Source');
    $email->refresh();

    $originalTemplateId = $email->template_id;

    $copy = $email->copy();
    $copy->refresh();

    expect($copy->template_id)->not->toBeNull();
    expect($copy->template_id)->not->toBe($originalTemplateId);
    expect($copy->template->source)->toBe(Template::SOURCE_UPLOADED);
    expect($copy->template->content)->toBe($html);
    expect($copy->isCustomHtml())->toBeTrue();
});

test('Email::deleteAndCleanup removes uploaded template', function () {
    ['customer' => $customer, 'list' => $list] = customHtmlFixture();

    $campaign = newCampaignForHtml($customer, $list);
    $email    = $campaign->email;

    $email->setCustomHtml('<html><body>Will be deleted</body></html>', 'Custom HTML Test Delete');
    $email->refresh();

    $templateId = $email->template_id;
    expect(DB::table('templates')->where('id', $templateId)->exists())->toBeTrue();

    // Detach email from campaign first (FK restricts direct email delete)
    DB::table('campaigns_lists_segments')->where('campaign_id', $campaign->id)->delete();
    DB::table('campaigns')->where('id', $campaign->id)->delete();

    $email->deleteAndCleanup();

    expect(DB::table('templates')->where('id', $templateId)->exists())->toBeFalse();
});

test('existing templates default to source=builder after migration backfill', function () {
    $template = Template::forceCreate([
        'uid'     => uniqid('tplhtml_'),
        'name'    => 'Custom HTML Test Backfill',
        'content' => '<html><body>x</body></html>',
        'json'    => Template::DEFAULT_BUILDER_JSON,
    ]);

    $template->refresh();
    expect($template->source)->toBe(Template::SOURCE_BUILDER);
    expect($template->isUploaded())->toBeFalse();
});