createTenant(); $firstAttachment = $this->createAttachment('first.png'); $secondAttachment = $this->createAttachment('second.png'); $tenant->mainCarouselImages()->attach([ $secondAttachment->id => ['orden' => 2], $firstAttachment->id => ['orden' => 1], ]); $attachments = $tenant->mainCarouselImages()->get(); $this->assertCount(2, $attachments); $this->assertTrue($attachments[0]->is($firstAttachment)); $this->assertTrue($attachments[1]->is($secondAttachment)); $this->assertSame([1, 2], $attachments->pluck('pivot.orden')->all()); } public function test_bootstrap_returns_all_main_carousel_image_urls_in_order(): void { $tenant = $this->createTenant(); $firstAttachment = $this->createAttachment('first.png'); $secondAttachment = $this->createAttachment('second.png'); $tenant->mainCarouselImages()->attach([ $secondAttachment->id => ['orden' => 20], $firstAttachment->id => ['orden' => 10], ]); $response = $this->getJson('/api/tenants/bootstrap/acme.com'); $response ->assertOk() ->assertJsonCount(2, 'data.main_carousel_images'); $urls = $response->json('data.main_carousel_images'); $this->assertStringContainsString($firstAttachment->key, $urls[0]); $this->assertStringContainsString($secondAttachment->key, $urls[1]); } public function test_show_returns_an_empty_main_carousel_images_array_when_the_tenant_has_no_images(): void { $tenant = $this->createTenant(); $this->getJson("/api/tenants/{$tenant->codigo}") ->assertOk() ->assertJsonPath('data.main_carousel_images', []); } public function test_store_uploads_and_attaches_main_carousel_images_in_request_order(): void { Storage::fake('s3'); $headerLogo = $this->createAttachment('header.png'); $footerLogo = $this->createAttachment('footer.png'); $response = $this ->withHeader('Accept', 'application/json') ->post('/api/tenants', [ ...$this->tenantPayload(), 'header_logo' => $headerLogo->key, 'footer_logo' => $footerLogo->key, 'main_carousel_images' => [ UploadedFile::fake()->image('first-carousel.png', 1200, 300), UploadedFile::fake()->image('second-carousel.png', 1200, 300), ], ]); $response ->assertCreated() ->assertJsonCount(2, 'data.main_carousel_images'); $tenant = Tenant::query()->where('codigo', 'new-acme')->firstOrFail(); $images = $tenant->mainCarouselImages()->get(); $this->assertSame( ['first-carousel.png', 'second-carousel.png'], $images->pluck('filename')->all() ); $this->assertSame([0, 1], $images->pluck('pivot.orden')->all()); Storage::disk('s3')->assertExists($images[0]->path); Storage::disk('s3')->assertExists($images[1]->path); } public function test_update_replaces_and_can_clear_main_carousel_images(): void { $tenant = $this->createTenant(); $oldImage = $this->createAttachment('old.png'); $firstImage = $this->createAttachment('first.png'); $secondImage = $this->createAttachment('second.png'); $tenant->mainCarouselImages()->attach($oldImage->id, ['orden' => 0]); $this->putJson("/api/tenants/{$tenant->codigo}", [ 'main_carousel_images' => [$secondImage->key, $firstImage->key], ]) ->assertOk() ->assertJsonCount(2, 'data.main_carousel_images'); $this->assertSame( [$secondImage->id, $firstImage->id], $tenant->mainCarouselImages()->pluck('attachments.id')->all() ); $this->assertDatabaseMissing('tenant_main_carousel_images', [ 'tenant_id' => $tenant->id, 'attachment_id' => $oldImage->id, ]); $this->putJson("/api/tenants/{$tenant->codigo}", [ 'main_carousel_images' => [], ]) ->assertOk() ->assertJsonPath('data.main_carousel_images', []); $this->assertDatabaseMissing('tenant_main_carousel_images', [ 'tenant_id' => $tenant->id, ]); } /** * @return array */ private function tenantPayload(): array { return [ 'codigo' => 'new-acme', 'nombre' => 'New Acme', 'dominio' => 'new-acme.com', 'primary_color' => '#111111', 'secondary_color' => '#222222', 'danger_color' => '#333333', 'success_color' => '#444444', 'header_bg_color' => '#ffffff', 'footer_bg_color' => '#ffffff', ]; } 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 { $key = (string) Str::uuid(); return Attachment::query()->create([ 'key' => $key, 'path' => "tenants/main-carousel/{$key}.png", 'filename' => $filename, 'type' => AttachmentType::Image, 'mime_type' => 'image/png', 'extension' => 'png', 'size' => 100, ]); } }