Files
portal/app/tests/Feature/Project/ProjectPhoneNormalizationTest.php
T

111 lines
4.1 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use App\Models\PricingTier;
use App\Models\Project;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Queue;
use Illuminate\Testing\TestResponse;
use Tests\Concerns\SharesSupplierPdo;
uses(DatabaseTransactions::class);
uses(SharesSupplierPdo::class);
beforeEach(function () {
Queue::fake();
DB::statement("SELECT set_config('app.current_tenant_id', '0', true)");
PricingTier::query()->create([
'tier_no' => 1,
'leads_in_tier' => null,
'price_per_lead_kopecks' => 5000, // 50₽/лид
'is_active' => true,
'effective_from' => now(),
]);
// Баланс заведомо большой — преflight всегда проходит, тест про нормализацию.
$this->tenant = Tenant::factory()->withRequisites()->create(['balance_rub' => '100000.00']);
$this->user = User::factory()->create(['tenant_id' => $this->tenant->id]);
});
function createCallProject(string $rawPhone, string $name = 'Звонок'): TestResponse
{
return test()->actingAs(test()->user)->postJson('/api/projects', [
'name' => $name,
'signal_type' => 'call',
'signal_identifier' => $rawPhone,
'daily_limit_target' => 5,
'regions' => [],
'delivery_days_mask' => 127,
]);
}
it('normalizes +7 (916) 123-45-67 to 79161234567 on create', function () {
createCallProject('+7 (916) 123-45-67')->assertCreated();
expect(Project::where('tenant_id', $this->tenant->id)->value('signal_identifier'))
->toBe('79161234567');
});
it('normalizes leading 8 to 7 on create', function () {
createCallProject('8 916 123 45 67')->assertCreated();
expect(Project::where('tenant_id', $this->tenant->id)->value('signal_identifier'))
->toBe('79161234567');
});
it('normalizes hyphenated 7-916-123-45-67 on create', function () {
createCallProject('7-916-123-45-67')->assertCreated();
expect(Project::where('tenant_id', $this->tenant->id)->value('signal_identifier'))
->toBe('79161234567');
});
it('keeps already canonical 79161234567 unchanged (idempotent)', function () {
createCallProject('79161234567')->assertCreated();
expect(Project::where('tenant_id', $this->tenant->id)->value('signal_identifier'))
->toBe('79161234567');
});
it('never stores a leading plus (routing matches without +)', function () {
createCallProject('+79161234567')->assertCreated();
$stored = Project::where('tenant_id', $this->tenant->id)->value('signal_identifier');
expect($stored)->toBe('79161234567')
->and($stored)->not->toContain('+');
});
it('rejects real garbage with a helpful message naming the on-screen field', function () {
$response = createCallProject('12345');
$response->assertStatus(422);
$msg = $response->json('errors.signal_identifier.0');
expect($msg)->toContain('79161234567') // показывает пример формата
->and($msg)->not->toContain('Источник'); // не всплывает внутреннее имя поля
});
it('does NOT normalize a site domain (only call is a phone)', function () {
test()->actingAs($this->user)->postJson('/api/projects', [
'name' => 'Сайт',
'signal_type' => 'site',
'signal_identifier' => 'my-site.ru',
'daily_limit_target' => 5,
'regions' => [],
'delivery_days_mask' => 127,
])->assertCreated();
expect(Project::where('tenant_id', $this->tenant->id)->value('signal_identifier'))
->toBe('my-site.ru');
});
it('normalizes phone on update of a call project', function () {
$project = Project::factory()->for($this->tenant)->create([
'signal_type' => 'call',
'signal_identifier' => '79990001122',
'is_active' => true,
'daily_limit_target' => 5,
]);
test()->actingAs($this->user)->patchJson("/api/projects/{$project->id}", [
'signal_identifier' => '+7 (916) 123-45-67',
])->assertOk();
expect($project->fresh()->signal_identifier)->toBe('79161234567');
});