Files
shopit-back/tests/Feature/Migrations/ContactPhoneNumbersTest.php

151 lines
7.0 KiB
PHP

<?php
namespace Tests\Feature\Migrations;
use App\Domains\Core\PhoneNumber\Models\PhoneNumber;
use App\Domains\Core\PhoneNumber\Resources\PhoneNumberResource;
use App\Domains\Core\Tenant\Models\Tenant;
use Illuminate\Database\QueryException;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Tests\TestCase;
class ContactPhoneNumbersTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
Schema::create('tenants', function (Blueprint $table): void {
$table->id();
$table->string('codigo')->unique();
$table->string('phone')->nullable();
$table->timestamps();
});
Schema::create('tenants_menues', function (Blueprint $table): void {
$table->id();
$table->string('tenant_code');
$table->string('menu_code');
$table->json('static_content')->nullable();
});
(require database_path('migrations/2026_09_30_000400_create_phone_numbers_and_tenant_phone_numbers_tables.php'))->up();
}
public function test_tenant_phone_wins_and_copy_is_idempotent_and_scoped(): void
{
DB::table('tenants')->insert([
['codigo' => 'a', 'phone' => '+54 341 111-1111'],
['codigo' => 'b', 'phone' => '+54 341 111-1111'],
['codigo' => 'c', 'phone' => null],
['codigo' => 'empty', 'phone' => ''],
]);
$this->contact('a', '+54 (341) 222-2222');
$this->contact('b', '54 (341) 1111111');
$this->contact('c', '+54 341 3333333');
$copy = require database_path('migrations/2026_09_30_000500_copy_tenant_and_contact_phone_numbers.php');
$copy->up();
$copy->up();
$this->assertDatabaseCount('phone_numbers', 4);
$a = Tenant::where('codigo', 'a')->firstOrFail();
$b = Tenant::where('codigo', 'b')->firstOrFail();
$this->assertSame('+54 341 111-1111', $a->mainPhoneNumber->number);
$this->assertCount(2, $a->phoneNumbers);
$this->assertCount(1, $b->phoneNumbers);
$this->assertNotSame($a->mainPhoneNumber->id, $b->mainPhoneNumber->id);
$this->assertSame('+54 341 3333333', Tenant::where('codigo', 'c')->firstOrFail()->mainPhoneNumber->number);
$this->assertNull(Tenant::where('codigo', 'empty')->firstOrFail()->mainPhoneNumber);
$this->assertSame('tel:+543411111111', $a->mainPhoneNumber->telUrl());
$mainResource = PhoneNumberResource::make($a->mainPhoneNumber)->resolve();
$this->assertSame('+54 341 111-1111', $mainResource['number']);
$this->assertSame('tel:+543411111111', $mainResource['tel_url']);
$resources = PhoneNumberResource::collection($a->phoneNumbers)->resolve();
$this->assertTrue($resources[0]['is_main']);
$this->assertFalse($resources[1]['is_main']);
$copy->down();
$this->assertDatabaseCount('phone_numbers', 4);
$this->assertDatabaseHas('tenants', ['codigo' => 'a', 'phone' => '+54 341 111-1111']);
}
public function test_database_rejects_two_main_numbers(): void
{
DB::table('tenants')->insert(['codigo' => 'a', 'phone' => '+54 341 1111111']);
$this->contact('a', '+54 341 2222222');
(require database_path('migrations/2026_09_30_000500_copy_tenant_and_contact_phone_numbers.php'))->up();
$this->expectException(QueryException::class);
DB::table('tenant_phone_numbers')->where('tenant_codigo', 'a')->update(['is_main' => true]);
}
public function test_invalid_contact_rolls_back_the_whole_copy(): void
{
DB::table('tenants')->insert(['codigo' => 'a', 'phone' => '+54 341 1111111']);
$this->contact('a', ['invalid']);
try {
(require database_path('migrations/2026_09_30_000500_copy_tenant_and_contact_phone_numbers.php'))->up();
$this->fail('Invalid legacy numbers must not be silently discarded.');
} catch (\RuntimeException $exception) {
$this->assertStringContainsString('Invalid phone number', $exception->getMessage());
$this->assertDatabaseCount('phone_numbers', 0);
}
}
public function test_a_number_cannot_be_linked_to_a_missing_tenant(): void
{
$id = DB::table('phone_numbers')->insertGetId(['label' => 'Contacto', 'number' => '123456']);
$this->expectException(QueryException::class);
DB::table('tenant_phone_numbers')->insert([
'tenant_codigo' => 'missing', 'phone_number_id' => $id, 'is_main' => true,
]);
}
public function test_it_splits_mobile_and_landline_numbers_and_builds_dialable_urls(): void
{
DB::table('phone_numbers')->insert([
['label' => 'Móvil', 'number' => '+54 9 (0341) 6658247'],
['label' => 'Fijo', 'number' => '+54 341 111-1111'],
['label' => 'Local', 'number' => '0341 1234567'],
['label' => 'Móvil sin signo', 'number' => '54 9 (0341) 6658247'],
]);
$migration = require database_path('migrations/2026_09_30_000700_split_phone_number_components.php');
$migration->up();
[$mobile, $landline, $local, $mobileWithoutPlus] = PhoneNumber::query()->orderBy('id')->get()->all();
$this->assertSame('+54', $mobile->country_code);
$this->assertSame('9', $mobile->mobile_prefix);
$this->assertSame('0341', $mobile->area_code);
$this->assertSame('6658247', $mobile->local_number);
$this->assertSame('+54 9 (0341) 6658247', $mobile->number);
$this->assertSame('tel:+5493416658247', $mobile->telUrl());
$this->assertSame('+54 341 1111111', $landline->number);
$this->assertSame('tel:+543411111111', $landline->telUrl());
$this->assertSame('0341 1234567', $local->number);
$this->assertSame('tel:03411234567', $local->telUrl());
$this->assertSame('+54 9 (0341) 6658247', $mobileWithoutPlus->number);
$resource = PhoneNumberResource::make($mobile)->resolve();
$this->assertSame('9', $resource['mobile_prefix']);
$this->assertSame('0341', $resource['area_code']);
$this->assertSame('tel:+5493416658247', $resource['tel_url']);
$created = PhoneNumber::query()->create([
'label' => 'Nuevo',
'area_code' => '0341',
'local_number' => '7777777',
]);
$this->assertSame('+54', $created->fresh()->country_code);
$this->assertSame('9', $created->fresh()->mobile_prefix);
$this->assertSame('+54 9 (0341) 7777777', $created->number);
$this->assertSame('tel:+5493417777777', $created->telUrl());
$migration->down();
$this->assertDatabaseHas('phone_numbers', ['id' => $mobile->id, 'number' => '+54 9 0341 6658247']);
}
private function contact(string $tenant, mixed $phone): void
{
DB::table('tenants_menues')->insert([
'tenant_code' => $tenant, 'menu_code' => 'help.contact',
'static_content' => json_encode(['phone' => $phone], JSON_THROW_ON_ERROR),
]);
}
}