Your IP : 216.73.216.79


Current Path : /var/www/html/dev/reddsis-dev/tests/Feature/
Upload File :
Current File : /var/www/html/dev/reddsis-dev/tests/Feature/ContentPhotoCRUDTest.php

<?php

namespace Tests\Feature;

use App\Models\Backend\BackendUser;
use App\Models\Backend\ContentPhotoGallery;
use App\Models\Backend\ContentPhotoGalleryTranslation;
use App\Models\Backend\ContentPhotoList;
use App\Models\Backend\Ref;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

class ContentPhotoCRUDTest extends TestCase
{
    use RefreshDatabase;

    protected BackendUser $user;
    protected array $langCodes = [];

    protected function setUp(): void
    {
        parent::setUp();

        Storage::fake('public');

        Ref::create(['cat' => 'LANGUAGE', 'code' => 'en', 'descr' => 'English', 'sort' => 1]);
        Ref::create(['cat' => 'LANGUAGE', 'code' => 'ms', 'descr' => 'Bahasa Melayu', 'sort' => 2]);
        Ref::create(['cat' => 'GALLERY_CAT', 'code' => 'GENERAL', 'descr' => 'General', 'sort' => 1]);
        Ref::create(['cat' => 'GALLERY_STATUS', 'code' => 'ACTIVE', 'descr' => 'Active', 'sort' => 1]);
        Ref::create(['cat' => 'PHOTO_STATUS', 'code' => 'ACTIVE', 'descr' => 'Active', 'sort' => 1]);

        $this->langCodes = ['en', 'ms'];

        foreach (['content-photo-gallery', 'content-photo-list'] as $prefix) {
            foreach (['view', 'create', 'update', 'delete'] as $action) {
                Permission::findOrCreate("{$prefix}.{$action}", 'admin');
            }
        }

        $role = Role::findOrCreate('admin', 'admin');
        $role->givePermissionTo(Permission::where('guard_name', 'admin')->get());

        $this->user = BackendUser::create([
            'username' => 'testadmin',
            'email' => 'test@example.com',
            'password' => bcrypt('password'),
            'first_name' => 'Test',
            'last_name' => 'Admin',
            'is_active' => true,
            'email_verified_at' => now(),
        ]);
        $this->user->assignRole($role);
        $this->user->givePermissionTo(Permission::where('guard_name', 'admin')->get());
    }

    protected function translations(array $mainOverrides = []): array
    {
        $base = [
            'en' => ['title' => 'English Title', 'descr' => '<p>English description</p>', 'main' => 1],
            'ms' => ['title' => 'Tajuk Bahasa Melayu', 'descr' => '<p>Penerangan Bahasa Melayu</p>', 'main' => 0],
        ];
        if (isset($mainOverrides['mainLang'])) {
            foreach ($base as $code => &$trans) {
                $trans['main'] = $code === $mainOverrides['mainLang'] ? 1 : 0;
            }
        }
        return $base;
    }

    protected function createGallery(array $extra = []): ContentPhotoGallery
    {
        return ContentPhotoGallery::create(array_merge([
            'gallery_code' => 'test-gallery',
            'gallery_sort' => 0,
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ], $extra));
    }

    protected function createTranslation(ContentPhotoGallery $gallery, string $lang, string $title, string $descr = '', int $main = 0): ContentPhotoGalleryTranslation
    {
        return ContentPhotoGalleryTranslation::create([
            'gallery_translation_parent_id' => $gallery->gallery_id,
            'gallery_translation_title' => $title,
            'gallery_translation_descr' => $descr,
            'gallery_translation_main' => $main,
            'gallery_translation_language' => $lang,
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);
    }

    // ─── GALLERY CRUD ───────────────────────────────────────

    public function test_gallery_index_page_loads()
    {
        $response = $this->actingAs($this->user, 'admin')->get(route('content-photo-gallery.index'));
        $response->assertStatus(200);
    }

    public function test_gallery_create_page_loads()
    {
        $response = $this->actingAs($this->user, 'admin')->get(route('content-photo-gallery.create'));
        $response->assertStatus(200);
    }

    public function test_gallery_store_with_translations()
    {
        $response = $this->actingAs($this->user, 'admin')->post(route('content-photo-gallery.store'), [
            'gallery_portal' => 'PORTAL1',
            'gallery_code' => 'test-slug',
            'gallery_status' => 'ACTIVE',
            'gallery_cat' => 'GENERAL',
            'gallery_date' => '2026-05-16',
            'gallery_location' => 'Kuala Lumpur',
            'translations' => $this->translations(),
        ]);

        $response->assertRedirect(route('content-photo-gallery.index'));

        $gallery = ContentPhotoGallery::where('gallery_code', 'test-slug')->first();
        $this->assertNotNull($gallery);

        $enTrans = ContentPhotoGalleryTranslation::where('gallery_translation_parent_id', $gallery->gallery_id)
            ->where('gallery_translation_language', 'en')->first();
        $this->assertNotNull($enTrans);
        $this->assertEquals('English Title', $enTrans->gallery_translation_title);
        $this->assertEquals(1, $enTrans->gallery_translation_main);

        $msTrans = ContentPhotoGalleryTranslation::where('gallery_translation_parent_id', $gallery->gallery_id)
            ->where('gallery_translation_language', 'ms')->first();
        $this->assertNotNull($msTrans);
        $this->assertEquals('Tajuk Bahasa Melayu', $msTrans->gallery_translation_title);
        $this->assertEquals(0, $msTrans->gallery_translation_main);
    }

    public function test_gallery_edit_page_loads()
    {
        $gallery = $this->createGallery();
        $this->createTranslation($gallery, 'en', 'Test Gallery', '<p>Desc</p>', 1);

        $response = $this->actingAs($this->user, 'admin')->get(route('content-photo-gallery.edit', $gallery->gallery_id));
        $response->assertStatus(200);
    }

    public function test_gallery_update_with_translations()
    {
        $gallery = $this->createGallery();
        $this->createTranslation($gallery, 'en', 'Original Title', '<p>Original</p>', 1);
        $this->createTranslation($gallery, 'ms', 'Tajuk Asal', '<p>Penerangan asal</p>', 0);

        $response = $this->actingAs($this->user, 'admin')->put(route('content-photo-gallery.update', $gallery->gallery_id), [
            'gallery_portal' => 'UPDATED_PORTAL',
            'gallery_code' => 'updated-slug',
            'gallery_status' => 'ACTIVE',
            'gallery_cat' => 'GENERAL',
            'gallery_date' => '2026-06-01',
            'gallery_location' => 'Putrajaya',
            'translations' => [
                'en' => ['title' => 'Updated EN Title', 'descr' => '<p>Updated EN desc</p>', 'main' => 1],
                'ms' => ['title' => 'Tajuk MS Dikemaskini', 'descr' => '<p>Penerangan MS</p>', 'main' => 0],
            ],
        ]);

        $response->assertRedirect(route('content-photo-gallery.index'));

        $gallery->fresh();
        $translations = ContentPhotoGalleryTranslation::where('gallery_translation_parent_id', $gallery->gallery_id)->get();
        $this->assertCount(2, $translations);

        $enTrans = $translations->firstWhere('gallery_translation_language', 'en');
        $this->assertEquals('Updated EN Title', $enTrans->gallery_translation_title);
        $this->assertEquals(1, $enTrans->gallery_translation_main);

        $msTrans = $translations->firstWhere('gallery_translation_language', 'ms');
        $this->assertEquals('Tajuk MS Dikemaskini', $msTrans->gallery_translation_title);
        $this->assertEquals(0, $msTrans->gallery_translation_main);
    }

    public function test_gallery_switch_main_language_on_update()
    {
        $gallery = $this->createGallery(['gallery_code' => 'switch-test']);
        $this->createTranslation($gallery, 'en', 'English Original', '<p>EN</p>', 1);

        $response = $this->actingAs($this->user, 'admin')->put(route('content-photo-gallery.update', $gallery->gallery_id), [
            'gallery_code' => 'switch-test',
            'translations' => [
                'ms' => ['title' => 'Tajuk Utama MS', 'descr' => '<p>Penerangan utama</p>', 'main' => 1],
                'en' => ['title' => 'English Secondary', 'descr' => '<p>EN secondary</p>', 'main' => 0],
            ],
        ]);

        $gallery->fresh();
        $msTrans = ContentPhotoGalleryTranslation::where('gallery_translation_parent_id', $gallery->gallery_id)
            ->where('gallery_translation_language', 'ms')->first();
        $this->assertEquals('Tajuk Utama MS', $msTrans->gallery_translation_title);
        $this->assertEquals(1, $msTrans->gallery_translation_main);

        $enTrans = ContentPhotoGalleryTranslation::where('gallery_translation_parent_id', $gallery->gallery_id)
            ->where('gallery_translation_language', 'en')->first();
        $this->assertEquals('English Secondary', $enTrans->gallery_translation_title);
        $this->assertEquals(0, $enTrans->gallery_translation_main);
    }

    public function test_gallery_delete_removes_photo_lists()
    {
        $gallery = $this->createGallery(['gallery_code' => 'to-delete']);
        $this->createTranslation($gallery, 'en', 'To Delete', '', 1);

        ContentPhotoList::create([
            'photo_gallery_id' => $gallery->gallery_id,
            'photo_main' => 1,
            'photo_url' => 'test.jpg',
            'photo_descr' => 'Test photo',
            'photo_language' => 'en',
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->actingAs($this->user, 'admin')->delete(route('content-photo-gallery.destroy', $gallery->gallery_id));
        $response->assertRedirect(route('content-photo-gallery.index'));

        $this->assertNull($gallery->fresh());
        $this->assertEquals(0, ContentPhotoList::count());
        $this->assertEquals(0, ContentPhotoGalleryTranslation::count());
    }

    // ─── PHOTO CRUD ─────────────────────────────────────────

    public function test_photo_create_page_loads()
    {
        $gallery = $this->createGallery();
        $this->createTranslation($gallery, 'en', 'Test Gallery', '', 1);

        $response = $this->actingAs($this->user, 'admin')->get(route('content-photo-list.create', ['gallery_id' => $gallery->gallery_id]));
        $response->assertStatus(200);
    }

    public function test_photo_store_with_translations()
    {
        $gallery = $this->createGallery();
        $this->createTranslation($gallery, 'en', 'Test Gallery', '', 1);

        $file = UploadedFile::fake()->image('photo.jpg', 800, 600);

        $response = $this->actingAs($this->user, 'admin')->post(route('content-photo-list.store'), [
            'photo_gallery_id' => $gallery->gallery_id,
            'photo_url' => $file,
            'photo_sort' => '5',
            'translations' => [
                'en' => ['descr' => 'English photo desc', 'main' => 1],
                'ms' => ['descr' => 'Penerangan foto MS', 'main' => 0],
            ],
        ]);

        $response->assertRedirect(route('content-photo-list.index'));

        $parent = ContentPhotoList::whereNull('photo_parent_id')->where('photo_main', 1)->first();
        $this->assertNotNull($parent);
        $this->assertEquals('English photo desc', $parent->photo_descr);
        $this->assertEquals('en', $parent->photo_language);
        $this->assertEquals(5, $parent->photo_sort);

        $sibling = ContentPhotoList::where('photo_parent_id', $parent->photo_id)->first();
        $this->assertNotNull($sibling);
        $this->assertEquals('Penerangan foto MS', $sibling->photo_descr);
    }

    public function test_photo_bulk_store_with_translations()
    {
        $gallery = $this->createGallery();
        $this->createTranslation($gallery, 'en', 'Bulk Gallery', '', 1);

        $files = [
            UploadedFile::fake()->image('photo1.jpg', 800, 600),
            UploadedFile::fake()->image('photo2.jpg', 800, 600),
        ];

        $response = $this->actingAs($this->user, 'admin')->post(route('content-photo-list.bulk-store'), [
            'photo_gallery_id' => $gallery->gallery_id,
            'files' => $files,
            'translations' => [
                'en' => ['descr' => 'Bulk EN desc', 'main' => 1],
                'ms' => ['descr' => 'Penerangan pukal MS', 'main' => 0],
            ],
        ]);

        $response->assertStatus(200);
        $response->assertJson(['success' => true]);

        $parents = ContentPhotoList::whereNull('photo_parent_id')->where('photo_main', 1)->get();
        $this->assertCount(2, $parents);

        foreach ($parents as $parent) {
            $this->assertEquals('Bulk EN desc', $parent->photo_descr);
            $this->assertEquals('en', $parent->photo_language);

            $sibling = ContentPhotoList::where('photo_parent_id', $parent->photo_id)->first();
            $this->assertNotNull($sibling);
            $this->assertEquals('Penerangan pukal MS', $sibling->photo_descr);
        }
    }

    public function test_photo_edit_page_loads()
    {
        $gallery = $this->createGallery();
        $this->createTranslation($gallery, 'en', 'G', '', 1);

        $photo = ContentPhotoList::create([
            'photo_gallery_id' => $gallery->gallery_id,
            'photo_main' => 1,
            'photo_url' => 'photo.jpg',
            'photo_descr' => 'Test',
            'photo_language' => 'en',
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->actingAs($this->user, 'admin')->get(route('content-photo-list.edit', $photo->photo_id));
        $response->assertStatus(200);
    }

    public function test_photo_update_with_translations()
    {
        $gallery = $this->createGallery();
        $this->createTranslation($gallery, 'en', 'G', '', 1);

        $photo = ContentPhotoList::create([
            'photo_gallery_id' => $gallery->gallery_id,
            'photo_main' => 1,
            'photo_url' => 'photo.jpg',
            'photo_descr' => 'Original',
            'photo_language' => 'en',
            'photo_sort' => 0,
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);
        ContentPhotoList::create([
            'photo_gallery_id' => $gallery->gallery_id,
            'photo_main' => 0,
            'photo_parent_id' => $photo->photo_id,
            'photo_url' => 'photo.jpg',
            'photo_descr' => 'Penerangan asal',
            'photo_language' => 'ms',
            'photo_sort' => 0,
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->actingAs($this->user, 'admin')->put(route('content-photo-list.update', $photo->photo_id), [
            'photo_gallery_id' => $gallery->gallery_id,
            'photo_sort' => '10',
            'translations' => [
                'en' => ['descr' => 'Updated EN desc', 'main' => 1],
                'ms' => ['descr' => 'Penerangan MS dikemaskini', 'main' => 0],
            ],
        ]);

        $response->assertRedirect(route('content-photo-list.index', ['gallery_id' => $gallery->gallery_id]));

        $parent = $photo->fresh();
        $this->assertEquals('Updated EN desc', $parent->photo_descr);
        $this->assertEquals(10, $parent->photo_sort);

        $siblings = ContentPhotoList::where('photo_parent_id', $photo->photo_id)->get();
        $this->assertCount(1, $siblings);
        $this->assertEquals('Penerangan MS dikemaskini', $siblings->first()->photo_descr);
    }

    public function test_photo_delete()
    {
        $gallery = $this->createGallery();
        $this->createTranslation($gallery, 'en', 'G', '', 1);

        $photo = ContentPhotoList::create([
            'photo_gallery_id' => $gallery->gallery_id,
            'photo_main' => 1,
            'photo_url' => 'photo.jpg',
            'photo_descr' => 'To delete',
            'photo_language' => 'en',
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->actingAs($this->user, 'admin')->delete(route('content-photo-list.destroy', $photo->photo_id));
        $response->assertRedirect();

        $this->assertNull($photo->fresh());
    }

    public function test_gallery_index_with_redirect_to_photos()
    {
        $gallery = $this->createGallery();
        $this->createTranslation($gallery, 'en', 'G', '', 1);

        ContentPhotoList::create([
            'photo_gallery_id' => $gallery->gallery_id,
            'photo_main' => 1,
            'photo_url' => 'p.jpg',
            'photo_descr' => 'P',
            'photo_language' => 'en',
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->actingAs($this->user, 'admin')
            ->get(route('content-photo-list.index', ['gallery_id' => $gallery->gallery_id]));
        $response->assertStatus(200);
        $response->assertSee('G');
        $response->assertSee('P');
    }
}