2026-05-22 18:10:30 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
use App\Models\Project;
|
|
|
|
|
use App\Models\Tenant;
|
|
|
|
|
use App\Models\User;
|
2026-05-22 18:48:03 +03:00
|
|
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
2026-05-22 18:10:30 +03:00
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
|
use Illuminate\Support\Facades\Queue;
|
|
|
|
|
|
2026-05-22 18:48:03 +03:00
|
|
|
uses(DatabaseTransactions::class);
|
2026-05-22 18:10:30 +03:00
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
|
Queue::fake();
|
|
|
|
|
|
|
|
|
|
$this->tenant = Tenant::factory()->create();
|
2026-05-22 18:48:03 +03:00
|
|
|
$this->user = User::factory()->create(['tenant_id' => $this->tenant->id]);
|
2026-05-22 18:10:30 +03:00
|
|
|
|
2026-05-22 18:48:03 +03:00
|
|
|
DB::statement('SET app.current_tenant_id = '.$this->tenant->id);
|
2026-05-22 18:10:30 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('logs project.created when a project is stored', function () {
|
|
|
|
|
$this->actingAs($this->user)->postJson('/api/projects', [
|
2026-05-22 18:48:03 +03:00
|
|
|
'name' => 'Окна СПб',
|
|
|
|
|
'signal_type' => 'site',
|
|
|
|
|
'signal_identifier' => 'okna-spb.ru',
|
2026-05-22 18:10:30 +03:00
|
|
|
'daily_limit_target' => 50,
|
2026-05-22 18:48:03 +03:00
|
|
|
'regions' => [],
|
2026-05-22 18:10:30 +03:00
|
|
|
'delivery_days_mask' => 127,
|
|
|
|
|
])->assertStatus(201);
|
|
|
|
|
|
|
|
|
|
$row = DB::table('tenant_operations_log')
|
|
|
|
|
->where('tenant_id', $this->tenant->id)
|
|
|
|
|
->where('event', 'project.created')
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
expect($row)->not->toBeNull();
|
|
|
|
|
expect($row->entity_type)->toBe('project');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('logs project.updated with before/after diff when a project is patched', function () {
|
|
|
|
|
$project = Project::factory()->create([
|
2026-05-22 18:48:03 +03:00
|
|
|
'tenant_id' => $this->tenant->id,
|
2026-05-22 18:10:30 +03:00
|
|
|
'daily_limit_target' => 10,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->actingAs($this->user)->patchJson("/api/projects/{$project->id}", [
|
|
|
|
|
'daily_limit_target' => 20,
|
|
|
|
|
])->assertOk();
|
|
|
|
|
|
|
|
|
|
$row = DB::table('tenant_operations_log')
|
|
|
|
|
->where('tenant_id', $this->tenant->id)
|
|
|
|
|
->where('event', 'project.updated')
|
|
|
|
|
->where('entity_id', $project->id)
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
expect($row)->not->toBeNull();
|
|
|
|
|
|
|
|
|
|
$before = json_decode($row->payload_before, true);
|
2026-05-22 18:48:03 +03:00
|
|
|
$after = json_decode($row->payload_after, true);
|
2026-05-22 18:10:30 +03:00
|
|
|
|
|
|
|
|
expect($before)->toHaveKey('daily_limit_target');
|
|
|
|
|
expect($after)->toHaveKey('daily_limit_target');
|
|
|
|
|
expect((int) $after['daily_limit_target'])->toBe(20);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('logs project.deleted when a project is destroyed', function () {
|
|
|
|
|
$project = Project::factory()->create(['tenant_id' => $this->tenant->id]);
|
|
|
|
|
|
|
|
|
|
$this->actingAs($this->user)->deleteJson("/api/projects/{$project->id}")
|
|
|
|
|
->assertNoContent();
|
|
|
|
|
|
|
|
|
|
$row = DB::table('tenant_operations_log')
|
|
|
|
|
->where('tenant_id', $this->tenant->id)
|
|
|
|
|
->where('event', 'project.deleted')
|
|
|
|
|
->where('entity_id', $project->id)
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
expect($row)->not->toBeNull();
|
|
|
|
|
expect($row->entity_type)->toBe('project');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('logs project.bulk_<action> when a bulk action is executed', function () {
|
|
|
|
|
$p1 = Project::factory()->create(['tenant_id' => $this->tenant->id, 'is_active' => true]);
|
|
|
|
|
$p2 = Project::factory()->create(['tenant_id' => $this->tenant->id, 'is_active' => true]);
|
|
|
|
|
|
|
|
|
|
$this->actingAs($this->user)->postJson('/api/projects/bulk', [
|
|
|
|
|
'action' => 'pause',
|
2026-05-22 18:48:03 +03:00
|
|
|
'ids' => [$p1->id, $p2->id],
|
2026-05-22 18:10:30 +03:00
|
|
|
])->assertOk()->assertJsonPath('updated', 2);
|
|
|
|
|
|
|
|
|
|
$row = DB::table('tenant_operations_log')
|
|
|
|
|
->where('tenant_id', $this->tenant->id)
|
|
|
|
|
->where('event', 'like', 'project.bulk_%')
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
expect($row)->not->toBeNull();
|
|
|
|
|
expect($row->entity_type)->toBe('project');
|
|
|
|
|
});
|