Skip to content

Commit

Permalink
[11.x] Refactor and add remaining test cases for the DatabaseFailedJo…
Browse files Browse the repository at this point in the history
…bProviderTest class (#53409)

* create a database and a provider in separate methods.

* add a method to create records in the failed_jobs table.

* add test cases for the remaining methods of the DatabaseFailedJobProvider class.

* rename some test cases and refactor to array_map in the DatabaseFailedJobProviderTest class.

* attempt to fix according to StyleCI.
  • Loading branch information
kevinb1989 authored Nov 5, 2024
1 parent fb0e5c0 commit ca0617a
Showing 1 changed file with 152 additions and 112 deletions.
264 changes: 152 additions & 112 deletions tests/Queue/DatabaseFailedJobProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,180 +6,220 @@
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Queue\Failed\DatabaseFailedJobProvider;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Date;
use Illuminate\Support\Str;
use PHPUnit\Framework\TestCase;
use RuntimeException;

class DatabaseFailedJobProviderTest extends TestCase
{
public function testCanFlushFailedJobs()
protected $db;

protected $provider;

public function setUp(): void
{
Date::setTestNow(Date::now());
parent::setUp();
$this->createDatabaseWithFailedJobTable()
->createProvider();
}

$db = new DB;
$db->addConnection([
'driver' => 'sqlite',
'database' => ':memory:',
]);
public function testCanGetAllFailedJobIds()
{
$this->assertEmpty($this->provider->ids());

$db->getConnection()->getSchemaBuilder()->create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->timestamp('failed_at')->useCurrent();
});
array_map(fn () => $this->createFailedJobsRecord(), range(1, 4));

$provider = new DatabaseFailedJobProvider($db->getDatabaseManager(), 'default', 'failed_jobs');
$this->assertCount(4, $this->provider->ids());
$this->assertSame([4, 3, 2, 1], $this->provider->ids());
}

$db->getConnection()->table('failed_jobs')->insert(['failed_at' => Date::now()->subDays(10)]);
$provider->flush();
$this->assertSame(0, $db->getConnection()->table('failed_jobs')->count());
public function testCanGetAllFailedJobs()
{
$this->assertEmpty($this->provider->all());

$db->getConnection()->table('failed_jobs')->insert(['failed_at' => Date::now()->subDays(10)]);
$provider->flush(15 * 24);
$this->assertSame(1, $db->getConnection()->table('failed_jobs')->count());
array_map(fn () => $this->createFailedJobsRecord(), range(1, 4));

$db->getConnection()->table('failed_jobs')->insert(['failed_at' => Date::now()->subDays(10)]);
$provider->flush(10 * 24);
$this->assertSame(0, $db->getConnection()->table('failed_jobs')->count());
$this->assertCount(4, $this->provider->all());
$this->assertSame(3, $this->provider->all()[1]->id);
$this->assertSame('default', $this->provider->all()[1]->queue);
}

public function testCanProperlyLogFailedJob()
public function testCanRetrieveFailedJobsById()
{
$db = new DB;
$db->addConnection([
'driver' => 'sqlite',
'database' => ':memory:',
]);
array_map(fn () => $this->createFailedJobsRecord(), range(1, 2));

$db->getConnection()->getSchemaBuilder()->create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
$this->assertNotNull($this->provider->find(1));
$this->assertNotNull($this->provider->find(2));
$this->assertNull($this->provider->find(3));
}

$uuid = Str::uuid();
public function testCanRemoveFailedJobsById()
{
$this->createFailedJobsRecord();

$this->assertFalse($this->provider->forget(2));
$this->assertSame(1, $this->failedJobsTable()->count());
$this->assertTrue($this->provider->forget(1));
$this->assertSame(0, $this->failedJobsTable()->count());
}

public function testCanPruneFailedJobs()
{
Carbon::setTestNow(Carbon::createFromDate(2024, 4, 28));

$this->createFailedJobsRecord(['failed_at' => Carbon::createFromDate(2024, 4, 24)]);
$this->createFailedJobsRecord(['failed_at' => Carbon::createFromDate(2024, 4, 26)]);

$this->provider->prune(Carbon::createFromDate(2024, 4, 23));
$this->assertSame(2, $this->failedJobsTable()->count());

$this->provider->prune(Carbon::createFromDate(2024, 4, 25));
$this->assertSame(1, $this->failedJobsTable()->count());

$this->provider->prune(Carbon::createFromDate(2024, 4, 30));
$this->assertSame(0, $this->failedJobsTable()->count());
}

public function testCanFlushFailedJobs()
{
Date::setTestNow(Date::now());

$this->createFailedJobsRecord(['failed_at' => Date::now()->subDays(10)]);
$this->provider->flush();
$this->assertSame(0, $this->failedJobsTable()->count());

$this->createFailedJobsRecord(['failed_at' => Date::now()->subDays(10)]);
$this->provider->flush(15 * 24);
$this->assertSame(1, $this->failedJobsTable()->count());

$this->createFailedJobsRecord(['failed_at' => Date::now()->subDays(10)]);
$this->provider->flush(10 * 24);
$this->assertSame(0, $this->failedJobsTable()->count());
}

public function testCanProperlyLogFailedJob()
{
$uuid = Str::uuid();
$exception = new Exception(mb_convert_encoding('ÐÑÙ0E\xE2\x�98\xA0World��7B¹!þÿ', 'ISO-8859-1', 'UTF-8'));
$provider = new DatabaseFailedJobProvider($db->getDatabaseManager(), 'default', 'failed_jobs');

$provider->log('database', 'default', json_encode(['uuid' => (string) $uuid]), $exception);
$this->provider->log('database', 'default', json_encode(['uuid' => (string) $uuid]), $exception);

$exception = (string) mb_convert_encoding($exception, 'UTF-8');

$this->assertSame(1, $db->getConnection()->table('failed_jobs')->count());
$this->assertSame($exception, $db->getConnection()->table('failed_jobs')->first()->exception);
$this->assertSame(1, $this->failedJobsTable()->count());
$this->assertSame($exception, $this->failedJobsTable()->first()->exception);
}

public function testJobsCanBeCounted()
{
$db = new DB;
$db->addConnection([
'driver' => 'sqlite',
'database' => ':memory:',
]);
$db->getConnection()->getSchemaBuilder()->create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
$provider = new DatabaseFailedJobProvider($db->getDatabaseManager(), 'default', 'failed_jobs');

$this->assertSame(0, $provider->count());
$this->assertSame(0, $this->provider->count());

$provider->log('database', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(1, $provider->count());
$this->provider->log('database', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(1, $this->provider->count());

$provider->log('database', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$provider->log('another-connection', 'another-queue', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(3, $provider->count());
$this->provider->log('database', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->provider->log('another-connection', 'another-queue', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(3, $this->provider->count());
}

public function testJobsCanBeCountedByConnection()
{
$db = new DB;
$db->addConnection([
'driver' => 'sqlite',
'database' => ':memory:',
]);
$db->getConnection()->getSchemaBuilder()->create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
$provider = new DatabaseFailedJobProvider($db->getDatabaseManager(), 'default', 'failed_jobs');
$this->provider->log('connection-1', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->provider->log('connection-2', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(1, $this->provider->count('connection-1'));
$this->assertSame(1, $this->provider->count('connection-2'));

$this->provider->log('connection-1', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(2, $this->provider->count('connection-1'));
$this->assertSame(1, $this->provider->count('connection-2'));
}

$provider->log('connection-1', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$provider->log('connection-2', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(1, $provider->count('connection-1'));
$this->assertSame(1, $provider->count('connection-2'));
public function testJobsCanBeCountedByQueue()
{
$this->provider->log('database', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->provider->log('database', 'queue-2', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(1, $this->provider->count(queue: 'queue-1'));
$this->assertSame(1, $this->provider->count(queue: 'queue-2'));

$this->provider->log('database', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(2, $this->provider->count(queue: 'queue-1'));
$this->assertSame(1, $this->provider->count(queue: 'queue-2'));
}

$provider->log('connection-1', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(2, $provider->count('connection-1'));
$this->assertSame(1, $provider->count('connection-2'));
public function testJobsCanBeCountedByQueueAndConnection()
{
$this->provider->log('connection-1', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->provider->log('connection-1', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->provider->log('connection-2', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->provider->log('connection-1', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->provider->log('connection-2', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->provider->log('connection-2', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());

$this->assertSame(2, $this->provider->count('connection-1', 'queue-99'));
$this->assertSame(1, $this->provider->count('connection-2', 'queue-99'));
$this->assertSame(1, $this->provider->count('connection-1', 'queue-1'));
$this->assertSame(2, $this->provider->count('connection-2', 'queue-1'));
}

public function testJobsCanBeCountedByQueue()
protected function createSimpleDatabaseWithFailedJobTable()
{
$db = new DB;
$db->addConnection([
'driver' => 'sqlite',
'database' => ':memory:',
]);

$db->getConnection()->getSchemaBuilder()->create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
$provider = new DatabaseFailedJobProvider($db->getDatabaseManager(), 'default', 'failed_jobs');

$provider->log('database', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$provider->log('database', 'queue-2', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(1, $provider->count(queue: 'queue-1'));
$this->assertSame(1, $provider->count(queue: 'queue-2'));

$provider->log('database', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(2, $provider->count(queue: 'queue-1'));
$this->assertSame(1, $provider->count(queue: 'queue-2'));
return $db;
}

public function testJobsCanBeCountedByQueueAndConnection()
protected function createDatabaseWithFailedJobTable()
{
$db = new DB;
$db->addConnection([
$this->db = new DB;
$this->db->addConnection([
'driver' => 'sqlite',
'database' => ':memory:',
]);
$db->getConnection()->getSchemaBuilder()->create('failed_jobs', function (Blueprint $table) {

$this->db->getConnection()->getSchemaBuilder()->create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
$provider = new DatabaseFailedJobProvider($db->getDatabaseManager(), 'default', 'failed_jobs');

$provider->log('connection-1', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$provider->log('connection-1', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$provider->log('connection-2', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$provider->log('connection-1', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$provider->log('connection-2', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$provider->log('connection-2', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());
$this->assertSame(2, $provider->count('connection-1', 'queue-99'));
$this->assertSame(1, $provider->count('connection-2', 'queue-99'));
$this->assertSame(1, $provider->count('connection-1', 'queue-1'));
$this->assertSame(2, $provider->count('connection-2', 'queue-1'));

return $this;
}

protected function createProvider(string $database = 'default', string $table = 'failed_jobs')
{
$this->provider = new DatabaseFailedJobProvider($this->db->getDatabaseManager(), $database, $table);

return $this;
}

protected function failedJobsTable()
{
return $this->db->getConnection()->table('failed_jobs');
}

protected function createFailedJobsRecord(array $overrides = [])
{
return $this->failedJobsTable()
->insert(array_merge([
'connection' => 'database',
'queue' => 'default',
'payload' => json_encode(['uuid' => (string) Str::uuid()]),
'exception' => new Exception('Whoops!'),
'failed_at' => Date::now()->subDays(10),
], $overrides));
}
}

0 comments on commit ca0617a

Please sign in to comment.