mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-10-07 21:33:18 +01:00
Add marker for auditable models without owner
Models implementing AuditableWithoutOwner intentionally have no audit owner, either because they belong to neither an organization nor a user, or because they and their audits have to be kept when the owner is deleted (for example billing records). Adds helpers and a scope on the audit model to find audits that are missing an owner although they should have one.
This commit is contained in:
committed by
Constantin Graf
parent
30a90f80e0
commit
f921452419
@@ -5,12 +5,15 @@ declare(strict_types=1);
|
||||
namespace Tests\Unit\Model;
|
||||
|
||||
use App\Models\Audit;
|
||||
use App\Models\Concerns\AuditableWithoutOwner;
|
||||
use App\Models\Member;
|
||||
use App\Models\Organization;
|
||||
use App\Models\Project;
|
||||
use App\Models\ProjectMember;
|
||||
use App\Models\TimeEntry;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
|
||||
#[CoversClass(Audit::class)]
|
||||
@@ -119,4 +122,52 @@ class AuditModelTest extends ModelTestAbstract
|
||||
$this->assertSame(0, Audit::query()->where('auditable_id', $organization->getKey())->count());
|
||||
$this->assertSame(1, Audit::query()->where('auditable_id', $otherUser->getKey())->count());
|
||||
}
|
||||
|
||||
public function test_auditable_types_without_owner_are_determined_by_the_marker_interface(): void
|
||||
{
|
||||
// Arrange
|
||||
$originalMorphMap = Relation::morphMap();
|
||||
$modelWithoutOwner = new class extends Model implements AuditableWithoutOwner {};
|
||||
Relation::morphMap(['model-without-owner' => $modelWithoutOwner::class]);
|
||||
|
||||
try {
|
||||
// Act
|
||||
$typesWithoutOwner = Audit::getAuditableTypesWithoutOwner();
|
||||
$isWithoutOwner = Audit::isAuditableTypeWithoutOwner('model-without-owner');
|
||||
$isTimeEntryWithoutOwner = Audit::isAuditableTypeWithoutOwner((new TimeEntry)->getMorphClass());
|
||||
|
||||
// Assert
|
||||
$this->assertContains('model-without-owner', $typesWithoutOwner);
|
||||
$this->assertNotContains((new TimeEntry)->getMorphClass(), $typesWithoutOwner);
|
||||
$this->assertTrue($isWithoutOwner);
|
||||
$this->assertFalse($isTimeEntryWithoutOwner);
|
||||
} finally {
|
||||
Relation::morphMap($originalMorphMap, false);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_scope_where_missing_owner_only_returns_audits_without_owner_whose_type_should_have_one(): void
|
||||
{
|
||||
// Arrange
|
||||
$originalMorphMap = Relation::morphMap();
|
||||
$modelWithoutOwner = new class extends Model implements AuditableWithoutOwner {};
|
||||
Relation::morphMap(['model-without-owner' => $modelWithoutOwner::class]);
|
||||
$organization = Organization::factory()->create();
|
||||
$user = User::factory()->create();
|
||||
Audit::query()->delete();
|
||||
$missingOwnerAudit = Audit::factory()->create(['auditable_type' => (new TimeEntry)->getMorphClass()]);
|
||||
Audit::factory()->create(['auditable_type' => (new TimeEntry)->getMorphClass(), 'owner_organization_id' => $organization->getKey()]);
|
||||
Audit::factory()->create(['owner_user_id' => $user->getKey()]);
|
||||
Audit::factory()->create(['auditable_type' => 'model-without-owner']);
|
||||
|
||||
try {
|
||||
// Act
|
||||
$auditIds = Audit::query()->whereMissingOwner()->pluck('id')->all();
|
||||
|
||||
// Assert
|
||||
$this->assertSame([$missingOwnerAudit->getKey()], $auditIds);
|
||||
} finally {
|
||||
Relation::morphMap($originalMorphMap, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user