307 lines
12 KiB
PHP
307 lines
12 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Category;
|
|
use App\Models\Order;
|
|
use App\Models\Product;
|
|
use App\Models\Setting;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Tests\TestCase;
|
|
|
|
class AdminContentTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected User $admin;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->admin = User::create([
|
|
'name' => 'Admin Jouwdriedee',
|
|
'email' => 'info@jouwdriedee.nl',
|
|
'password' => bcrypt('Jw3D!x9#QmK7$vR2'),
|
|
'is_admin' => true,
|
|
]);
|
|
}
|
|
|
|
public function test_guest_is_redirected_to_login_when_accessing_admin(): void
|
|
{
|
|
$response = $this->get(route('admin.content.index'));
|
|
|
|
$response->assertRedirect(route('login'));
|
|
}
|
|
|
|
public function test_regular_customer_cannot_access_admin(): void
|
|
{
|
|
$customer = User::create([
|
|
'name' => 'Klant Piet',
|
|
'email' => 'piet@example.com',
|
|
'password' => bcrypt('secret1234'),
|
|
'is_admin' => false,
|
|
]);
|
|
|
|
$response = $this->actingAs($customer)->get(route('admin.content.index'));
|
|
|
|
$response->assertRedirect(route('home'));
|
|
$response->assertSessionHas('error');
|
|
}
|
|
|
|
public function test_admin_content_editor_loads_successfully(): void
|
|
{
|
|
$response = $this->actingAs($this->admin)->get(route('admin.content.index'));
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertSee('Homepage Hero');
|
|
$response->assertSee('Shop Content & Stijl CMS', false);
|
|
}
|
|
|
|
public function test_admin_can_update_layout_and_texts(): void
|
|
{
|
|
$payload = [
|
|
'site_name' => 'Mega 3D Shop',
|
|
'hero_title' => 'Custom 3D Speelgoed & Figuren',
|
|
'hero_subtitle' => 'Nieuwe custom introductietekst voor de winkel.',
|
|
'hero_primary_btn_text' => 'Direct Winkelen',
|
|
'usp_title' => 'Waarom kiezen voor onze prints?',
|
|
'footer_email' => 'hallo@mega3d.nl',
|
|
'announcement_enabled' => '1',
|
|
'announcement_text' => 'Tijdelijke actie: gratis verzending!',
|
|
];
|
|
|
|
$response = $this->actingAs($this->admin)->post(route('admin.content.update'), $payload);
|
|
|
|
$response->assertRedirect(route('admin.content.index'));
|
|
$response->assertSessionHas('success');
|
|
|
|
$this->assertSame('Mega 3D Shop', Setting::get('site_name'));
|
|
$this->assertSame('Custom 3D Speelgoed & Figuren', Setting::get('hero_title'));
|
|
$this->assertSame('hallo@mega3d.nl', Setting::get('footer_email'));
|
|
|
|
// Homepage should now display the updated content!
|
|
$homeResponse = $this->get(route('home'));
|
|
$homeResponse->assertStatus(200);
|
|
$homeResponse->assertSee('Custom 3D Speelgoed & Figuren');
|
|
$homeResponse->assertSee('Nieuwe custom introductietekst voor de winkel.');
|
|
$homeResponse->assertSee('Direct Winkelen');
|
|
$homeResponse->assertSee('Waarom kiezen voor onze prints?');
|
|
$homeResponse->assertSee('hallo@mega3d.nl');
|
|
$homeResponse->assertSee('Tijdelijke actie: gratis verzending!');
|
|
}
|
|
|
|
public function test_admin_can_reset_content_to_defaults(): void
|
|
{
|
|
Setting::set('hero_title', 'Tijdelijke Titel');
|
|
$this->assertSame('Tijdelijke Titel', Setting::get('hero_title'));
|
|
|
|
$response = $this->actingAs($this->admin)->post(route('admin.content.reset'));
|
|
$response->assertRedirect(route('admin.content.index'));
|
|
|
|
$this->assertNull(Setting::get('hero_title'));
|
|
}
|
|
|
|
public function test_admin_can_view_and_edit_products(): void
|
|
{
|
|
$category = Category::create([
|
|
'name' => 'Fidgets',
|
|
'slug' => 'fidgets',
|
|
]);
|
|
|
|
$product = Product::create([
|
|
'name' => 'Test Fidget Draak',
|
|
'slug' => 'test-fidget-draak',
|
|
'category_id' => $category->id,
|
|
'base_price' => 12.50,
|
|
'short_description' => 'Korte test',
|
|
'description' => 'Uitgebreide test beschrijving',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
// Products index
|
|
$indexResponse = $this->actingAs($this->admin)->get(route('admin.products.index'));
|
|
$indexResponse->assertStatus(200);
|
|
$indexResponse->assertSee('Test Fidget Draak');
|
|
|
|
// Edit page
|
|
$editResponse = $this->actingAs($this->admin)->get(route('admin.products.edit', $product));
|
|
$editResponse->assertStatus(200);
|
|
$editResponse->assertSee('Test Fidget Draak');
|
|
|
|
// Update product
|
|
$updateResponse = $this->actingAs($this->admin)->put(route('admin.products.update', $product), [
|
|
'name' => 'Aangepaste Fidget Draak',
|
|
'category_id' => $category->id,
|
|
'base_price' => 18.00,
|
|
'short_description' => 'Geüpdatete korte test',
|
|
'description' => 'Nieuwe lange beschrijving',
|
|
'is_active' => 1,
|
|
'is_featured' => 1,
|
|
]);
|
|
|
|
$updateResponse->assertRedirect(route('admin.products.index'));
|
|
$this->assertDatabaseHas('products', [
|
|
'id' => $product->id,
|
|
'name' => 'Aangepaste Fidget Draak',
|
|
'base_price' => 18.00,
|
|
]);
|
|
}
|
|
|
|
public function test_admin_can_view_orders(): void
|
|
{
|
|
$order = Order::create([
|
|
'order_number' => 'ORD-TEST-999',
|
|
'customer_name' => 'Jan Jansen',
|
|
'customer_email' => 'jan@example.com',
|
|
'shipping_street' => 'Dorpstraat',
|
|
'shipping_number' => '1',
|
|
'shipping_postal_code' => '1234AB',
|
|
'shipping_city' => 'Amsterdam',
|
|
'subtotal' => 25.00,
|
|
'shipping_cost' => 0.00,
|
|
'total' => 25.00,
|
|
'status' => 'pending',
|
|
]);
|
|
|
|
$response = $this->actingAs($this->admin)->get(route('admin.orders.index'));
|
|
$response->assertStatus(200);
|
|
$response->assertSee('ORD-TEST-999');
|
|
$response->assertSee('Jan Jansen');
|
|
|
|
$showResponse = $this->actingAs($this->admin)->get(route('admin.orders.show', $order));
|
|
$showResponse->assertStatus(200);
|
|
$showResponse->assertSee('ORD-TEST-999');
|
|
}
|
|
|
|
public function test_admin_can_update_product_images_and_gallery(): void
|
|
{
|
|
$category = Category::create([
|
|
'name' => 'Fidget Gadgets',
|
|
'slug' => 'fidget-gadgets-gallery-test',
|
|
]);
|
|
|
|
$product = Product::create([
|
|
'category_id' => $category->id,
|
|
'name' => 'Multi Foto Draak',
|
|
'slug' => 'multi-foto-draak',
|
|
'short_description' => 'Test met meerdere fotos',
|
|
'description' => 'Test beschrijving met galerij',
|
|
'base_price' => 19.95,
|
|
'image_url' => 'https://cdn.example.com/cover.jpg',
|
|
'gallery_images' => ['https://cdn.example.com/photo1.jpg', 'https://cdn.example.com/photo2.jpg'],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
// Edit page loads with visual image gallery
|
|
$editResponse = $this->actingAs($this->admin)->get(route('admin.products.edit', $product));
|
|
$editResponse->assertStatus(200);
|
|
$editResponse->assertSee('Productafbeeldingen & Fotogalerij', false);
|
|
$editResponse->assertSee('Hoofdafbeelding (Cover)');
|
|
|
|
// Update product with new cover and extra gallery images
|
|
$updateResponse = $this->actingAs($this->admin)->put(route('admin.products.update', $product), [
|
|
'name' => 'Multi Foto Draak Bijgewerkt',
|
|
'category_id' => $category->id,
|
|
'base_price' => 21.50,
|
|
'short_description' => 'Geüpdatet',
|
|
'description' => 'Nieuwe omschrijving',
|
|
'image_url' => 'https://cdn.example.com/new-cover.jpg',
|
|
'gallery_images' => [
|
|
'https://cdn.example.com/photo1.jpg',
|
|
'https://cdn.example.com/photo2.jpg',
|
|
'https://cdn.example.com/photo3.jpg',
|
|
'https://cdn.example.com/new-cover.jpg', // Should be excluded because it matches cover
|
|
],
|
|
'is_active' => 1,
|
|
]);
|
|
|
|
$updateResponse->assertRedirect(route('admin.products.index'));
|
|
|
|
$product->refresh();
|
|
$this->assertEquals('https://cdn.example.com/new-cover.jpg', $product->image_url);
|
|
$this->assertCount(3, $product->gallery_images);
|
|
$this->assertContains('https://cdn.example.com/photo3.jpg', $product->gallery_images);
|
|
$this->assertNotContains('https://cdn.example.com/new-cover.jpg', $product->gallery_images);
|
|
|
|
// Storefront product details page shows the multi-image gallery
|
|
$shopResponse = $this->get(route('product.show', $product->slug));
|
|
$shopResponse->assertStatus(200);
|
|
$shopResponse->assertSee('https://cdn.example.com/new-cover.jpg');
|
|
$shopResponse->assertSee('https://cdn.example.com/photo1.jpg');
|
|
$shopResponse->assertSee('https://cdn.example.com/photo3.jpg');
|
|
}
|
|
|
|
public function test_admin_can_upload_product_image(): void
|
|
{
|
|
Storage::fake('public');
|
|
|
|
$onePixelJpeg = base64_decode('/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAP//////////////////////////////////////////////////////////////////////////////////////wgALCAABAAEBAREA/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/aAAgBAQABPxA=');
|
|
$file = UploadedFile::fake()->createWithContent('test-print-photo.jpg', $onePixelJpeg);
|
|
|
|
$response = $this->actingAs($this->admin)->postJson(route('admin.products.upload-image'), [
|
|
'image' => $file,
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJson([
|
|
'success' => true,
|
|
]);
|
|
|
|
$url = $response->json('url');
|
|
$this->assertStringStartsWith('/storage/products/', $url);
|
|
|
|
$storagePath = str_replace('/storage/', '', $url);
|
|
Storage::disk('public')->assertExists($storagePath);
|
|
}
|
|
|
|
public function test_admin_can_toggle_webshop_offline_mode(): void
|
|
{
|
|
$this->assertEquals('0', Setting::get('shop_offline', '0'));
|
|
|
|
// Toggle offline via admin button
|
|
$response = $this->actingAs($this->admin)->post(route('admin.toggle-offline'));
|
|
$response->assertRedirect();
|
|
Setting::flushCache();
|
|
$this->assertEquals('1', Setting::get('shop_offline'));
|
|
|
|
// Logout admin so subsequent requests are unauthenticated guest requests
|
|
auth()->logout();
|
|
$this->flushSession();
|
|
|
|
// Guest visitor receives 503 with big red offline banner
|
|
$guestResponse = $this->get(route('home'));
|
|
$guestResponse->assertStatus(503);
|
|
$guestResponse->assertSee('Aan deze webshop wordt hard gewerkt', false);
|
|
$guestResponse->assertSee('Webshop Tijdelijk Offline');
|
|
|
|
// Other customer routes are blocked
|
|
$catalogResponse = $this->get(route('catalog'));
|
|
$catalogResponse->assertStatus(503);
|
|
|
|
// Login page remains accessible
|
|
$loginResponse = $this->get(route('login'));
|
|
$loginResponse->assertStatus(200);
|
|
|
|
// Admin can still view storefront normally with preview banner
|
|
$adminShopResponse = $this->actingAs($this->admin)->get(route('home'));
|
|
$adminShopResponse->assertStatus(200);
|
|
$adminShopResponse->assertSee('OFFLINE BEHEERDERS-PREVIEW');
|
|
|
|
// Toggle back online
|
|
$this->actingAs($this->admin)->post(route('admin.toggle-offline'));
|
|
Setting::flushCache();
|
|
$this->assertEquals('0', Setting::get('shop_offline'));
|
|
|
|
// Logout admin and verify guest can visit normally again
|
|
auth()->logout();
|
|
$this->flushSession();
|
|
|
|
$guestOnlineResponse = $this->get(route('home'));
|
|
$guestOnlineResponse->assertStatus(200);
|
|
}
|
|
}
|