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

namespace Tests\Unit;

use App\Model\Campaign;
use Mockery;
use Tests\TestCase;

class CampaignLastErrorTest extends TestCase
{
    protected function tearDown(): void
    {
        Mockery::close();

        parent::tearDown();
    }

    public function test_last_error_is_stored_as_json_text_but_read_as_message()
    {
        $campaign = new Campaign();

        $campaign->setLastError(
            'SMTP timeout',
            "#0 /app/Jobs/RunCampaign.php:105\n#1 /vendor/laravel/framework"
        );

        $raw = $campaign->getAttributes()['last_error'];

        $this->assertJson($raw);
        $this->assertSame([
            'message' => 'SMTP timeout',
            'backtrace' => "#0 /app/Jobs/RunCampaign.php:105\n#1 /vendor/laravel/framework",
        ], json_decode($raw, true));

        $this->assertSame('SMTP timeout', $campaign->last_error);
        $this->assertSame('SMTP timeout', $campaign->extractErrorMessage());
    }

    public function test_plain_string_last_error_is_wrapped_as_message_with_empty_backtrace()
    {
        $campaign = new Campaign();
        $campaign->last_error = "Error scheduling campaign: Boom\n#0 /app/Jobs/RunCampaign.php:105\n#1 /vendor/laravel/framework";

        $payload = json_decode($campaign->getAttributes()['last_error'], true);

        $this->assertSame("Error scheduling campaign: Boom\n#0 /app/Jobs/RunCampaign.php:105\n#1 /vendor/laravel/framework", $payload['message']);
        $this->assertSame('', $payload['backtrace']);
        $this->assertSame("Error scheduling campaign: Boom\n#0 /app/Jobs/RunCampaign.php:105\n#1 /vendor/laravel/framework", $campaign->last_error);
    }

    public function test_set_error_persists_json_payload_via_mutator()
    {
        $campaign = Mockery::mock(Campaign::class)->makePartial();
        $campaign->shouldReceive('save')->once()->andReturn(true);

        $campaign->setError('Failed to start campaign: Connection refused', '#0 socket_connect()');

        $payload = json_decode($campaign->getAttributes()['last_error'], true);

        $this->assertSame('Failed to start campaign: Connection refused', $payload['message']);
        $this->assertSame('#0 socket_connect()', $payload['backtrace']);
        $this->assertSame('Failed to start campaign: Connection refused', $campaign->last_error);
    }

    public function test_last_error_attribute_setter_rejects_non_string_value()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->expectExceptionMessage(
            'Campaign last_error attribute only accepts null or string. Use setLastError($message, $backtrace = null) for structured errors.'
        );

        $campaign = new Campaign();
        $campaign->last_error = ['message' => 'Only message'];
    }

    public function test_set_last_error_rejects_empty_message()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->expectExceptionMessage('Campaign last_error message cannot be empty.');

        $campaign = new Campaign();
        $campaign->setLastError('', '#0 socket_connect()');
    }

    public function test_set_last_error_rejects_null_message()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->expectExceptionMessage('Campaign last_error message must be a string and cannot be null.');

        $campaign = new Campaign();
        $campaign->setLastError(null);
    }
}