164 lines
8.7 KiB
PHP
164 lines
8.7 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Address;
|
|
|
|
use App\Domains\Core\Address\Models\Address;
|
|
use App\Domains\Core\Tenant\Models\Tenant;
|
|
use App\Domains\Core\Tenant\Resources\TenantResource;
|
|
use App\Domains\Ticketing\Event\Models\Event;
|
|
use App\Domains\Ticketing\Event\Resources\EventResource;
|
|
use App\Domains\Ticketing\Event\Resources\PublicEventResource;
|
|
use App\Domains\Ticketing\Event\Services\EventAddressService;
|
|
use App\Domains\Ticketing\Event\Services\PublicEventService;
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Tests\TestCase;
|
|
|
|
class AddressPresentationTest extends TestCase
|
|
{
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
Schema::create('tenants', function (Blueprint $table): void {
|
|
$table->id();
|
|
$table->string('codigo')->unique();
|
|
});
|
|
Schema::create('events', function (Blueprint $table): void {
|
|
$table->id();
|
|
$table->string('tenant_code')->nullable();
|
|
$table->string('title')->nullable();
|
|
$table->string('subtitle')->nullable();
|
|
$table->timestamp('published_at')->nullable();
|
|
$table->foreignId('attachment_id')->nullable();
|
|
$table->string('location')->nullable();
|
|
$table->json('exact_location')->nullable();
|
|
$table->timestamps();
|
|
});
|
|
(require database_path('migrations/2026_09_30_000000_create_addresses_and_tenant_addresses_tables.php'))->up();
|
|
(require database_path('migrations/2026_09_30_000200_add_address_id_to_events.php'))->up();
|
|
}
|
|
|
|
public function test_tenant_response_exposes_all_addresses_main_address_and_a_separate_event_address(): void
|
|
{
|
|
DB::table('tenants')->insert(['codigo' => 'acme']);
|
|
$tenant = Tenant::where('codigo', 'acme')->firstOrFail();
|
|
$tenant->forceFill((new Tenant)->getAttributes());
|
|
$principal = Address::create(['label' => 'Principal', 'address_text' => 'Sede 123', 'latitude' => 0, 'longitude' => 0]);
|
|
$secondary = Address::create(['label' => 'Sucursal', 'address_text' => 'Otra calle 456']);
|
|
$venue = Address::create(['label' => 'Predio', 'address_text' => 'Evento 789', 'latitude' => -32.9431184, 'longitude' => -60.6437991]);
|
|
$tenant->addresses()->attach($principal->id, ['is_main' => true]);
|
|
$tenant->addresses()->attach($secondary->id);
|
|
$tenant->load(['addresses', 'mainAddress']);
|
|
foreach (['headerLogo', 'footerLogo', 'favicon', 'headerBackgroundImage', 'footerBackgroundImage', 'storefrontWebsiteType'] as $relation) {
|
|
$tenant->setRelation($relation, null);
|
|
}
|
|
$event = $this->presentedEvent($venue, $tenant);
|
|
$tenant->setRelation('activeEvent', $event);
|
|
$data = (new TenantResource($tenant))->response()->getData(true)['data'];
|
|
|
|
$this->assertCount(2, $data['addresses']);
|
|
$this->assertTrue($data['addresses'][0]['is_main']);
|
|
$this->assertFalse($data['addresses'][1]['is_main']);
|
|
$this->assertSame(0, $data['main_address']['latitude']);
|
|
$this->assertNull($data['addresses'][1]['latitude']);
|
|
$this->assertSame($venue->id, $data['event']['address']['id']);
|
|
$this->assertSame(-32.9431184, $data['event']['address']['latitude']);
|
|
$this->assertSame('Evento 789', $data['event']['address']['address_text']);
|
|
$this->assertSame('Anterior', $data['event']['location']);
|
|
$this->assertArrayNotHasKey('is_main', $data['event']['address']);
|
|
}
|
|
|
|
public function test_public_and_admin_event_responses_use_the_same_canonical_address(): void
|
|
{
|
|
$address = Address::create(['label' => 'Predio', 'address_text' => 'Nueva 123', 'latitude' => 0, 'longitude' => -60.6437991]);
|
|
$event = $this->presentedEvent($address, new Tenant);
|
|
foreach ([EventResource::class, PublicEventResource::class] as $resource) {
|
|
$data = (new $resource($event))->response()->getData(true)['data'];
|
|
$this->assertSame('Nueva 123', $data['address']['address_text']);
|
|
$this->assertSame(0, $data['address']['latitude']);
|
|
$this->assertSame(-60.6437991, $data['address']['longitude']);
|
|
$this->assertSame('Anterior', $data['location']);
|
|
$this->assertSame(20, $data['exact_location']['longitude']);
|
|
}
|
|
|
|
$event->setRelation('address', null);
|
|
$data = (new PublicEventResource($event))->response()->getData(true)['data'];
|
|
$this->assertNull($data['address']);
|
|
$this->assertSame('Anterior', $data['location']);
|
|
$address->update(['latitude' => null, 'longitude' => null]);
|
|
$event->setRelation('address', $address);
|
|
$data = (new PublicEventResource($event))->response()->getData(true)['data'];
|
|
$this->assertNull($data['address']['latitude']);
|
|
$this->assertSame(20, $data['exact_location']['longitude']);
|
|
}
|
|
|
|
public function test_editing_event_location_preserves_canonical_coordinates_unless_explicitly_changed(): void
|
|
{
|
|
$address = Address::create(['label' => 'Predio', 'address_text' => 'Anterior', 'latitude' => 0, 'longitude' => -60]);
|
|
$event = Event::create(['address_id' => $address->id, 'location' => 'Nueva', 'exact_location' => ['latitude' => 10, 'longitude' => 20]]);
|
|
DB::transaction(fn () => app(EventAddressService::class)->syncLocation($event));
|
|
$this->assertSame('Nueva', $address->fresh()->address_text);
|
|
$this->assertSame('0.0000000', $address->fresh()->latitude);
|
|
$this->assertDatabaseCount('addresses', 1);
|
|
|
|
$event->exact_location = null;
|
|
DB::transaction(fn () => app(EventAddressService::class)->syncLocation($event, true));
|
|
$this->assertNull($address->fresh()->latitude);
|
|
$this->assertNull($address->fresh()->longitude);
|
|
}
|
|
|
|
public function test_editing_a_shared_event_address_does_not_change_tenant_or_other_event_addresses(): void
|
|
{
|
|
DB::table('tenants')->insert(['codigo' => 'acme']);
|
|
$tenant = Tenant::where('codigo', 'acme')->firstOrFail();
|
|
$address = Address::create(['label' => 'Compartida', 'address_text' => 'Original', 'latitude' => -32, 'longitude' => -60]);
|
|
$tenant->addresses()->attach($address->id, ['is_main' => true]);
|
|
$event = Event::create(['address_id' => $address->id, 'location' => 'Nueva ubicación']);
|
|
$other = Event::create(['address_id' => $address->id, 'location' => 'Original']);
|
|
|
|
DB::transaction(fn () => app(EventAddressService::class)->syncLocation($event));
|
|
|
|
$this->assertSame('Original', $address->fresh()->address_text);
|
|
$this->assertSame($address->id, $other->fresh()->address_id);
|
|
$this->assertSame($address->id, $tenant->mainAddress->id);
|
|
$this->assertNotSame($address->id, $event->fresh()->address_id);
|
|
$this->assertSame('Nueva ubicación', $event->fresh()->address->address_text);
|
|
$this->assertSame('-32.0000000', $event->fresh()->address->latitude);
|
|
}
|
|
|
|
public function test_public_event_search_uses_its_address_and_loads_it_for_the_response(): void
|
|
{
|
|
DB::table('tenants')->insert(['codigo' => 'acme']);
|
|
$tenant = Tenant::where('codigo', 'acme')->firstOrFail();
|
|
$address = Address::create(['label' => 'Predio', 'address_text' => 'Dirección nueva']);
|
|
$event = Event::create([
|
|
'tenant_code' => 'acme', 'title' => 'Festival', 'location' => 'Dirección anterior',
|
|
'address_id' => $address->id, 'published_at' => now()->subMinute(),
|
|
]);
|
|
$service = app(PublicEventService::class);
|
|
$page = $service->list($tenant, 'nueva', 1);
|
|
$this->assertSame($event->id, $page->items()[0]->id);
|
|
$this->assertTrue($page->items()[0]->relationLoaded('address'));
|
|
$this->assertSame(0, $service->list($tenant, 'anterior', 1)->total());
|
|
}
|
|
|
|
public function test_editing_an_unlinked_event_creates_its_address(): void
|
|
{
|
|
$event = Event::create(['location' => 'Predio 123', 'exact_location' => ['latitude' => -32, 'longitude' => -60]]);
|
|
DB::transaction(fn () => app(EventAddressService::class)->syncLocation($event));
|
|
$this->assertSame('Predio 123', $event->fresh()->address->address_text);
|
|
$this->assertSame('-60.0000000', $event->fresh()->address->longitude);
|
|
$this->assertDatabaseCount('tenant_addresses', 0);
|
|
}
|
|
|
|
private function presentedEvent(?Address $address, Tenant $tenant): Event
|
|
{
|
|
$event = new Event(['location' => 'Anterior', 'exact_location' => ['latitude' => 10, 'longitude' => 20]]);
|
|
$event->setRelation('address', $address)->setRelation('tenant', $tenant)
|
|
->setRelation('socialMedia', collect())->setRelation('dates', collect())->setRelation('attachment', null);
|
|
|
|
return $event;
|
|
}
|
|
}
|