Skip to content

Commit

Permalink
feat(database): Mimic save (timestamps, exists, generated id) for saf…
Browse files Browse the repository at this point in the history
…e unique save action
  • Loading branch information
pionl committed Oct 10, 2022
1 parent 8cb734f commit 77e40a6
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ public function execute(Model $model, Closure $setupClosure, int $maxTries = 20,
return $this->execute($model, $setupClosure, $maxTries, $tries + 1);
}

$model->updateTimestamps();

if ($expectation->setId !== null) {
$model->setAttribute('id', $expectation->setId);
$model->exists = true;
}

return $result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public function __construct(
public readonly bool $fail = false,
public readonly int $maxTries = 20,
public readonly int $tries = 1,
public readonly string|int|null $setId = null,
) {
}
}
30 changes: 30 additions & 0 deletions tests/Feature/Database/Models/TestNoDates.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Tests\LaraStrict\Feature\Database\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
* @property int $test
* @property Carbon|null $deleted_at
*/
class TestNoDates extends Model
{
use HasFactory;
use SoftDeletes;

final public const CREATED_AT = null;

final public const UPDATED_AT = null;

final public const AttributeTest = 'test';

final public const AttributeDeletedAt = 'deleted_at';

protected $fillable = [self::AttributeTest];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

declare(strict_types=1);

namespace Tests\LaraStrict\Feature\Testing\Database\Contracts;

use LaraStrict\Testing\Database\Contracts\SafeUniqueSaveActionContractAssert;
use LaraStrict\Testing\Database\Contracts\SafeUniqueSaveActionContractExpectation;
use Tests\LaraStrict\Feature\Database\Models\Test;
use Tests\LaraStrict\Feature\Database\Models\TestNoDates;
use Tests\LaraStrict\Feature\TestCase;

class SafeUniqueSaveActionContractAssertTest extends TestCase
{
public function testExecuteOneTry(): void
{
$model = new Test();
$expectations = [new SafeUniqueSaveActionContractExpectation($model)];
$expectedResult = 'test1';

$this->assertExecute($expectations, $model, $expectedResult);
}

public function testExecuteOneTryNoDates(): void
{
$model = new TestNoDates();
$expectations = [new SafeUniqueSaveActionContractExpectation($model)];
$expectedResult = 'test1';

$this->assertExecute($expectations, $model, $expectedResult);
}

public function testExecuteOneTryWithSetId(): void
{
$model = new Test();
$expectations = [new SafeUniqueSaveActionContractExpectation($model, setId: 1)];
$expectedResult = 'test1';

$this->assertExecute($expectations, $model, $expectedResult, 1);
}

public function testExecuteTwoTries(): void
{
$model = new Test();
$expectations = [
new SafeUniqueSaveActionContractExpectation($model, fail: true),
new SafeUniqueSaveActionContractExpectation($model, tries: 2),
];
$expectedResult = 'test2';

$this->assertExecute($expectations, $model, $expectedResult);
}

public function testExecuteTwoTriesWithId(): void
{
$model = new Test();
$expectations = [
new SafeUniqueSaveActionContractExpectation($model, fail: true, setId: 2),
new SafeUniqueSaveActionContractExpectation($model, tries: 2, setId: 1),
];
$expectedResult = 'test2';

$this->assertExecute($expectations, $model, $expectedResult, 1);
}

protected function assertExecute(
array $expectations,
Test|TestNoDates $model,
string $expectedResult,
?int $expectedId = null
): void {
$assert = new SafeUniqueSaveActionContractAssert($expectations);

$calls = 0;
$result = $assert->execute($model, function (Test|TestNoDates $model, int $tries) use (&$calls) {
++$calls;
$this->assertEquals($calls, $tries);
return 'test' . $calls;
});

$this->assertEquals($expectedResult, $result);

$createdAt = $model->getAttribute('created_at');
$updatedAt = $model->getAttribute('updated_at');
if ($model instanceof TestNoDates) {
$this->assertNull($createdAt);
$this->assertNull($updatedAt);
} else {
$this->assertNotNull($createdAt);
$this->assertNotNull($updatedAt);
}

$this->assertEquals($expectedId, $model->getKey());
}
}

This file was deleted.

0 comments on commit 77e40a6

Please sign in to comment.