feat(projects): source+name dedup on update

This commit is contained in:
Дмитрий
2026-05-21 07:35:11 +03:00
parent 5427cdc740
commit e2fb20ef05
3 changed files with 42 additions and 0 deletions
@@ -41,6 +41,18 @@ class ProjectService
|| array_key_exists('daily_limit_target', $data)
|| array_key_exists('delivery_days_mask', $data);
if (array_key_exists('signal_identifier', $data) || array_key_exists('sms_senders', $data) || array_key_exists('sms_keyword', $data)) {
$this->assertSourceUnique($project->tenant_id, array_merge([
'signal_type' => $project->signal_type,
'signal_identifier' => $project->signal_identifier,
'sms_senders' => $project->sms_senders,
'sms_keyword' => $project->sms_keyword,
], $data), exceptId: $project->id);
}
if (array_key_exists('name', $data)) {
$this->assertNameUnique($project->tenant_id, (string) $data['name'], exceptId: $project->id);
}
$project->update($data);
if ($needsResync) {
@@ -6,8 +6,10 @@ use App\Models\Project;
use App\Models\Tenant;
use App\Services\Project\ProjectService;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\Facades\Queue;
beforeEach(function () {
Queue::fake();
$this->tenant = Tenant::factory()->create(['balance_leads' => 100]);
});
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
use App\Models\Tenant;
use App\Services\Project\ProjectService;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\Facades\Queue;
beforeEach(fn () => Queue::fake());
it('blocks update that collides source with another project of same tenant', function () {
$tenant = Tenant::factory()->create(['balance_leads' => 100]);
$svc = app(ProjectService::class);
$a = $svc->create($tenant, ['name' => 'A', 'signal_type' => 'call', 'signal_identifier' => '79991110000', 'daily_limit_target' => 5, 'regions' => [], 'delivery_days_mask' => 31]);
$b = $svc->create($tenant, ['name' => 'B', 'signal_type' => 'call', 'signal_identifier' => '79992220000', 'daily_limit_target' => 5, 'regions' => [], 'delivery_days_mask' => 31]);
expect(fn () => $svc->update($b, ['signal_identifier' => '79991110000']))
->toThrow(HttpResponseException::class);
});
it('allows update keeping same source on the same project', function () {
$tenant = Tenant::factory()->create(['balance_leads' => 100]);
$svc = app(ProjectService::class);
$a = $svc->create($tenant, ['name' => 'A', 'signal_type' => 'call', 'signal_identifier' => '79991110000', 'daily_limit_target' => 5, 'regions' => [], 'delivery_days_mask' => 31]);
$updated = $svc->update($a, ['signal_identifier' => '79991110000', 'daily_limit_target' => 7]);
expect($updated->daily_limit_target)->toBe(7);
});