File: /home/xedaptot/be.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);
}
}