| Current Path : /var/www/html/dev/reddsis-dev/tests/Feature/ |
| 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');
}
}