From c66d2019d626b596ae04987ba5e1034ed6376fca Mon Sep 17 00:00:00 2001 From: ncoronel Date: Thu, 23 Jul 2026 14:54:42 -0300 Subject: [PATCH] feat(social-media): add SocialMedia model, migration, and tests for tenant associations --- app/Domains/Tenant/Models/SocialMedia.php | 34 ++++++ app/Domains/Tenant/Models/Tenant.php | 17 +++ ...7_23_000200_create_social_media_tables.php | 43 +++++++ .../Feature/Tenant/TenantSocialMediaTest.php | 108 ++++++++++++++++++ 4 files changed, 202 insertions(+) create mode 100644 app/Domains/Tenant/Models/SocialMedia.php create mode 100644 database/migrations/2026_07_23_000200_create_social_media_tables.php create mode 100644 tests/Feature/Tenant/TenantSocialMediaTest.php diff --git a/app/Domains/Tenant/Models/SocialMedia.php b/app/Domains/Tenant/Models/SocialMedia.php new file mode 100644 index 0000000..b308a24 --- /dev/null +++ b/app/Domains/Tenant/Models/SocialMedia.php @@ -0,0 +1,34 @@ + + */ + public function tenants(): BelongsToMany + { + return $this->belongsToMany( + Tenant::class, + 'tenant_social_media', + 'social_media_code', + 'tenant_code', + 'code', + 'codigo' + ) + ->withPivot('url') + ->withTimestamps(); + } +} diff --git a/app/Domains/Tenant/Models/Tenant.php b/app/Domains/Tenant/Models/Tenant.php index 938797d..133d785 100644 --- a/app/Domains/Tenant/Models/Tenant.php +++ b/app/Domains/Tenant/Models/Tenant.php @@ -94,6 +94,23 @@ class Tenant extends Model return $this->hasMany(CatalogItem::class, 'tenant_code', 'codigo'); } + /** + * @return BelongsToMany + */ + public function socialMedia(): BelongsToMany + { + return $this->belongsToMany( + SocialMedia::class, + 'tenant_social_media', + 'tenant_code', + 'social_media_code', + 'codigo', + 'code' + ) + ->withPivot('url') + ->withTimestamps(); + } + public function menues(): BelongsToMany { return $this->belongsToMany( diff --git a/database/migrations/2026_07_23_000200_create_social_media_tables.php b/database/migrations/2026_07_23_000200_create_social_media_tables.php new file mode 100644 index 0000000..6796341 --- /dev/null +++ b/database/migrations/2026_07_23_000200_create_social_media_tables.php @@ -0,0 +1,43 @@ +id(); + $table->string('code')->unique(); + $table->string('icon'); + $table->string('name'); + $table->timestamps(); + }); + + Schema::create('tenant_social_media', function (Blueprint $table): void { + $table->id(); + $table->string('tenant_code'); + $table->string('social_media_code'); + $table->string('url'); + $table->timestamps(); + + $table->foreign('tenant_code') + ->references('codigo') + ->on('tenants') + ->cascadeOnDelete(); + $table->foreign('social_media_code') + ->references('code') + ->on('social_media') + ->cascadeOnDelete(); + $table->unique(['tenant_code', 'social_media_code']); + }); + } + + public function down(): void + { + Schema::dropIfExists('tenant_social_media'); + Schema::dropIfExists('social_media'); + } +}; diff --git a/tests/Feature/Tenant/TenantSocialMediaTest.php b/tests/Feature/Tenant/TenantSocialMediaTest.php new file mode 100644 index 0000000..388f188 --- /dev/null +++ b/tests/Feature/Tenant/TenantSocialMediaTest.php @@ -0,0 +1,108 @@ +assertEqualsCanonicalizing([ + 'id', + 'code', + 'icon', + 'name', + 'created_at', + 'updated_at', + ], Schema::getColumnListing('social_media')); + + $this->assertEqualsCanonicalizing([ + 'id', + 'tenant_code', + 'social_media_code', + 'url', + 'created_at', + 'updated_at', + ], Schema::getColumnListing('tenant_social_media')); + } + + public function test_a_tenant_can_have_social_media_with_its_own_url(): void + { + $tenant = $this->createTenant(); + $instagram = SocialMedia::query()->create([ + 'code' => 'instagram', + 'icon' => 'instagram', + 'name' => 'Instagram', + ]); + + $tenant->socialMedia()->attach($instagram->code, [ + 'url' => 'https://instagram.com/acme', + ]); + + $this->assertTrue($tenant->socialMedia()->firstOrFail()->is($instagram)); + $this->assertSame( + 'https://instagram.com/acme', + $tenant->socialMedia()->firstOrFail()->pivot->url + ); + $this->assertTrue($instagram->tenants()->firstOrFail()->is($tenant)); + } + + public function test_deleting_a_social_media_deletes_its_tenant_associations(): void + { + $tenant = $this->createTenant(); + $instagram = SocialMedia::query()->create([ + 'code' => 'instagram', + 'icon' => 'instagram', + 'name' => 'Instagram', + ]); + $tenant->socialMedia()->attach($instagram->code, [ + 'url' => 'https://instagram.com/acme', + ]); + + $instagram->delete(); + + $this->assertDatabaseMissing('tenant_social_media', [ + 'tenant_code' => $tenant->codigo, + 'social_media_code' => $instagram->code, + ]); + } + + private function createTenant(): Tenant + { + $headerLogo = $this->createAttachment('header.png'); + $footerLogo = $this->createAttachment('footer.png'); + + return Tenant::query()->create([ + 'codigo' => 'acme', + 'nombre' => 'Acme', + 'dominio' => 'acme.com', + 'primary_color' => '#111111', + 'secondary_color' => '#222222', + 'danger_color' => '#333333', + 'success_color' => '#444444', + 'header_bg_color' => '#ffffff', + 'footer_bg_color' => '#ffffff', + 'header_logo_id' => $headerLogo->id, + 'footer_logo_id' => $footerLogo->id, + ]); + } + + private function createAttachment(string $filename): Attachment + { + return Attachment::query()->create([ + 'path' => "test/{$filename}", + 'filename' => $filename, + 'type' => AttachmentType::Image, + 'mime_type' => 'image/png', + ]); + } +}