feat(setting): implementasi maintenance mode
- membuat config baru untuk secret key - implementasi test - menyesuaikan validasi - kasih return type
This commit is contained in:
parent
2b5983fb2a
commit
224ea30a2a
@ -4,7 +4,6 @@
|
||||
|
||||
use App\Rules\PhoneNumber;
|
||||
use App\Settings\ContactSettings;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Livewire\Form;
|
||||
|
||||
class ContactForm extends Form
|
||||
@ -20,10 +19,10 @@ class ContactForm extends Form
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'phone_number' => ['required', 'string', new PhoneNumber],
|
||||
'email' => ['nullable', 'email', 'max:100', Rule::unique('users', 'email')],
|
||||
'address' => ['required', 'string', 'max:255'],
|
||||
'map_embed' => ['nullable', 'string'],
|
||||
'phone_number' => ['required', 'string', 'min:10', 'max:20', new PhoneNumber],
|
||||
'email' => ['nullable', 'email', 'max:100'],
|
||||
'address' => ['required', 'string', 'min:10', 'max:500'],
|
||||
'map_embed' => ['nullable', 'string', 'max:2000'],
|
||||
];
|
||||
}
|
||||
|
||||
@ -31,16 +30,17 @@ public function validationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'phone_number' => 'nomor telepon',
|
||||
'email' => 'email',
|
||||
'address' => 'alamat',
|
||||
'map_embed' => 'map embed',
|
||||
'map_embed' => 'embed peta',
|
||||
];
|
||||
}
|
||||
|
||||
public function setSettings(ContactSettings $settings): void
|
||||
{
|
||||
$this->address = $settings->address;
|
||||
$this->phone_number = $settings->phone_number;
|
||||
$this->email = $settings->email;
|
||||
$this->address = $settings->address;
|
||||
$this->map_embed = $settings->map_embed;
|
||||
}
|
||||
|
||||
@ -48,9 +48,9 @@ public function update(ContactSettings $settings): void
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$settings->address = $this->address;
|
||||
$settings->phone_number = $this->phone_number;
|
||||
$settings->email = $this->email;
|
||||
$settings->address = $this->address;
|
||||
$settings->map_embed = $this->map_embed;
|
||||
|
||||
$settings->save();
|
||||
|
||||
@ -18,13 +18,23 @@ class GeneralForm extends Form
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'site_name' => ['required', 'string', 'max:100'],
|
||||
'site_tagline' => ['required', 'string', 'max:150'],
|
||||
'site_description' => ['required', 'string'],
|
||||
'site_name' => ['required', 'string', 'min:1', 'max:100'],
|
||||
'site_tagline' => ['required', 'string', 'min:1', 'max:150'],
|
||||
'site_description' => ['required', 'string', 'min:10', 'max:500'],
|
||||
'maintenance_mode' => ['required', 'boolean'],
|
||||
];
|
||||
}
|
||||
|
||||
public function validationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'site_name' => 'nama situs',
|
||||
'site_tagline' => 'tagline situs',
|
||||
'site_description' => 'deskripsi situs',
|
||||
'maintenance_mode' => 'mode maintenance',
|
||||
];
|
||||
}
|
||||
|
||||
public function setSettings(GeneralSettings $settings): void
|
||||
{
|
||||
$this->site_name = $settings->site_name;
|
||||
@ -33,7 +43,7 @@ public function setSettings(GeneralSettings $settings): void
|
||||
$this->maintenance_mode = $settings->maintenance_mode;
|
||||
}
|
||||
|
||||
public function update(GeneralSettings $settings): void
|
||||
public function update(GeneralSettings $settings): bool
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
@ -43,5 +53,7 @@ public function update(GeneralSettings $settings): void
|
||||
$settings->maintenance_mode = $this->maintenance_mode;
|
||||
|
||||
$settings->save();
|
||||
|
||||
return $settings->maintenance_mode;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,15 +28,30 @@ class SeoForm extends Form
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'meta_description' => ['required', 'string'],
|
||||
'meta_keywords' => ['required', 'string'],
|
||||
'meta_author' => ['required', 'string', 'max:150'],
|
||||
'og_image' => ['nullable', 'string', 'max:255'],
|
||||
'meta_description' => ['required', 'string', 'min:10', 'max:160'],
|
||||
'meta_keywords' => ['required', 'string', 'min:3', 'max:255'],
|
||||
'meta_author' => ['required', 'string', 'min:1', 'max:150'],
|
||||
'og_image' => ['nullable', 'string', 'max:500', 'url'],
|
||||
'og_title' => ['nullable', 'string', 'max:255'],
|
||||
'og_description' => ['nullable', 'string'],
|
||||
'og_type' => ['nullable', 'string', 'max:50'],
|
||||
'twitter_card' => ['nullable', 'string', 'max:50'],
|
||||
'canonical_url' => ['nullable', 'string', 'max:255'],
|
||||
'og_description' => ['nullable', 'string', 'max:300'],
|
||||
'og_type' => ['nullable', 'string', 'max:50', 'in:website,article,product'],
|
||||
'twitter_card' => ['nullable', 'string', 'max:50', 'in:summary,summary_large_image'],
|
||||
'canonical_url' => ['nullable', 'string', 'max:500', 'url'],
|
||||
];
|
||||
}
|
||||
|
||||
public function validationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'meta_description' => 'meta deskripsi',
|
||||
'meta_keywords' => 'meta kata kunci',
|
||||
'meta_author' => 'meta penulis',
|
||||
'og_image' => 'gambar Open Graph',
|
||||
'og_title' => 'judul Open Graph',
|
||||
'og_description' => 'deskripsi Open Graph',
|
||||
'og_type' => 'tipe Open Graph',
|
||||
'twitter_card' => 'kartu Twitter',
|
||||
'canonical_url' => 'URL kanonis',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -19,15 +19,15 @@ class SocialForm extends Form
|
||||
|
||||
public ?string $telegram = null;
|
||||
|
||||
protected function rules(): array
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'facebook' => ['nullable', 'url'],
|
||||
'instagram' => ['nullable', 'url'],
|
||||
'youtube' => ['nullable', 'url'],
|
||||
'tiktok' => ['nullable', 'url'],
|
||||
'whatsapp' => ['required', 'url'],
|
||||
'telegram' => ['nullable', 'url'],
|
||||
'facebook' => ['nullable', 'url', 'max:255'],
|
||||
'instagram' => ['nullable', 'url', 'max:255'],
|
||||
'youtube' => ['nullable', 'url', 'max:255'],
|
||||
'tiktok' => ['nullable', 'url', 'max:255'],
|
||||
'whatsapp' => ['nullable', 'url', 'max:255'],
|
||||
'telegram' => ['nullable', 'url', 'max:255'],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
use App\Traits\WithAuthorization;
|
||||
use App\Traits\WithToast;
|
||||
use App\Traits\WithUpdatedData;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Livewire\Attributes\Title;
|
||||
use Livewire\Component;
|
||||
|
||||
@ -35,7 +37,7 @@ public function mount(
|
||||
ContactSettings $contactSettings,
|
||||
SocialSettings $socialSettings,
|
||||
SeoSettings $seoSettings,
|
||||
) {
|
||||
): void {
|
||||
$this->generalForm->setSettings($generalSettings);
|
||||
|
||||
$this->contactForm->setSettings($contactSettings);
|
||||
@ -45,16 +47,26 @@ public function mount(
|
||||
$this->seoForm->setSettings($seoSettings);
|
||||
}
|
||||
|
||||
public function updateGeneral(GeneralSettings $generalSettings)
|
||||
public function updateGeneral(GeneralSettings $generalSettings): void
|
||||
{
|
||||
$this->canOrAbort('update general settings');
|
||||
|
||||
$this->generalForm->update($generalSettings);
|
||||
$isMaintenance = $this->generalForm->update($generalSettings);
|
||||
|
||||
if ($isMaintenance) {
|
||||
Artisan::call('down', [
|
||||
'--secret' => config('app.maintenance.secret'),
|
||||
]);
|
||||
|
||||
$this->redirect('/'.config('app.maintenance.secret'));
|
||||
}
|
||||
|
||||
Artisan::call('up');
|
||||
|
||||
$this->toast('Pengaturan umum berhasil diperbarui.');
|
||||
}
|
||||
|
||||
public function updateContact(ContactSettings $contactSettings)
|
||||
public function updateContact(ContactSettings $contactSettings): void
|
||||
{
|
||||
$this->canOrAbort('update contact settings');
|
||||
|
||||
@ -63,7 +75,7 @@ public function updateContact(ContactSettings $contactSettings)
|
||||
$this->toast('Pengaturan kontak berhasil diperbarui.');
|
||||
}
|
||||
|
||||
public function updateSocial(SocialSettings $socialSettings)
|
||||
public function updateSocial(SocialSettings $socialSettings): void
|
||||
{
|
||||
$this->canOrAbort('update social settings');
|
||||
|
||||
@ -72,7 +84,7 @@ public function updateSocial(SocialSettings $socialSettings)
|
||||
$this->toast('Pengaturan media sosial berhasil diperbarui.');
|
||||
}
|
||||
|
||||
public function updateSeo(SeoSettings $seoSettings)
|
||||
public function updateSeo(SeoSettings $seoSettings): void
|
||||
{
|
||||
$this->canOrAbort('update seo settings');
|
||||
|
||||
@ -81,7 +93,7 @@ public function updateSeo(SeoSettings $seoSettings)
|
||||
$this->toast('Pengaturan SEO berhasil diperbarui.');
|
||||
}
|
||||
|
||||
public function render()
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.studio.setting.application', [
|
||||
'pageTitle' => 'Aplikasi',
|
||||
|
||||
@ -121,6 +121,7 @@
|
||||
'maintenance' => [
|
||||
'driver' => env('APP_MAINTENANCE_DRIVER', 'file'),
|
||||
'store' => env('APP_MAINTENANCE_STORE', 'database'),
|
||||
'secret' => env('APP_MAINTENANCE_SECRET'),
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
301
tests/Feature/Livewire/Studio/Setting/ApplicationTest.php
Normal file
301
tests/Feature/Livewire/Studio/Setting/ApplicationTest.php
Normal file
@ -0,0 +1,301 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Studio\Setting\Application;
|
||||
use App\Models\User;
|
||||
use App\Settings\ContactSettings;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\SeoSettings;
|
||||
use App\Settings\SocialSettings;
|
||||
use Database\Seeders\RolePermissionSeeder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
$this->seed(RolePermissionSeeder::class);
|
||||
|
||||
$this->user = User::factory()
|
||||
->active()
|
||||
->create();
|
||||
|
||||
$this->ownerRole = Role::where('name', 'Owner')->first();
|
||||
|
||||
$this->user->roles()->attach($this->ownerRole->id);
|
||||
});
|
||||
|
||||
function mountApplicationComponent(User $user)
|
||||
{
|
||||
return Livewire::actingAs($user)->test(Application::class);
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Component Rendering & Mount
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
it('renders page successfully', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->assertViewIs('livewire.studio.setting.application')
|
||||
->assertViewHas('pageTitle', 'Aplikasi');
|
||||
});
|
||||
|
||||
it('mounts with settings loaded', function () {
|
||||
$component = mountApplicationComponent($this->user);
|
||||
|
||||
expect($component->generalForm->site_name)->toBe('Yadi Parfum');
|
||||
expect($component->contactForm->phone_number)->toBe('083816931711');
|
||||
expect($component->socialForm->whatsapp)->toBe('https://wa.me/6283816931711');
|
||||
expect($component->seoForm->meta_description)->toBe('Nikmati pengalaman wangi berkualitas tinggi dengan parfum refill dan produk unggulan dari Yadi Parfum.');
|
||||
});
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| General Settings Update
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
it('updates general settings successfully', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('generalForm.site_name', 'Updated Site Name')
|
||||
->set('generalForm.site_tagline', 'Updated Tagline')
|
||||
->set('generalForm.site_description', 'Updated description for the site')
|
||||
->set('generalForm.maintenance_mode', true)
|
||||
->call('updateGeneral')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$settings = app(GeneralSettings::class);
|
||||
expect($settings->site_name)->toBe('Updated Site Name');
|
||||
expect($settings->site_tagline)->toBe('Updated Tagline');
|
||||
expect($settings->site_description)->toBe('Updated description for the site');
|
||||
expect($settings->maintenance_mode)->toBe(true);
|
||||
});
|
||||
|
||||
it('validates general settings required fields', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('generalForm.site_name', '')
|
||||
->set('generalForm.site_tagline', '')
|
||||
->set('generalForm.site_description', '')
|
||||
->call('updateGeneral')
|
||||
->assertHasErrors([
|
||||
'generalForm.site_name' => 'required',
|
||||
'generalForm.site_tagline' => 'required',
|
||||
'generalForm.site_description' => 'required',
|
||||
]);
|
||||
});
|
||||
|
||||
it('validates general settings field lengths', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('generalForm.site_name', str_repeat('a', 101))
|
||||
->set('generalForm.site_tagline', str_repeat('a', 151))
|
||||
->call('updateGeneral')
|
||||
->assertHasErrors([
|
||||
'generalForm.site_name' => 'max',
|
||||
'generalForm.site_tagline' => 'max',
|
||||
]);
|
||||
});
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Contact Settings Update
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
it('updates contact settings successfully', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('contactForm.phone_number', '0812 3456 7890')
|
||||
->set('contactForm.email', 'contact@example.com')
|
||||
->set('contactForm.address', 'Updated Address 123')
|
||||
->set('contactForm.map_embed', '<iframe>map</iframe>')
|
||||
->call('updateContact')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$settings = app(ContactSettings::class);
|
||||
|
||||
expect($settings->phone_number)->toBe('0812 3456 7890');
|
||||
expect($settings->email)->toBe('contact@example.com');
|
||||
expect($settings->address)->toBe('Updated Address 123');
|
||||
expect($settings->map_embed)->toBe('<iframe>map</iframe>');
|
||||
});
|
||||
|
||||
it('validates contact settings required fields', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('contactForm.phone_number', '')
|
||||
->set('contactForm.address', '')
|
||||
->call('updateContact')
|
||||
->assertHasErrors([
|
||||
'contactForm.phone_number' => 'required',
|
||||
'contactForm.address' => 'required',
|
||||
]);
|
||||
});
|
||||
|
||||
it('validates contact settings email format', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('contactForm.phone_number', '+628123456789')
|
||||
->set('contactForm.email', 'invalid-email')
|
||||
->set('contactForm.address', 'Valid Address')
|
||||
->call('updateContact')
|
||||
->assertHasErrors([
|
||||
'contactForm.email' => 'email',
|
||||
]);
|
||||
});
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Social Settings Update
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
it('updates social settings successfully', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('socialForm.facebook', 'https://facebook.com/page')
|
||||
->set('socialForm.instagram', 'https://instagram.com/page')
|
||||
->set('socialForm.youtube', 'https://youtube.com/channel')
|
||||
->set('socialForm.tiktok', 'https://tiktok.com/@user')
|
||||
->set('socialForm.whatsapp', 'https://wa.me/123456789')
|
||||
->set('socialForm.telegram', 'https://t.me/channel')
|
||||
->call('updateSocial')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$settings = app(SocialSettings::class);
|
||||
expect($settings->facebook)->toBe('https://facebook.com/page');
|
||||
expect($settings->instagram)->toBe('https://instagram.com/page');
|
||||
expect($settings->youtube)->toBe('https://youtube.com/channel');
|
||||
expect($settings->tiktok)->toBe('https://tiktok.com/@user');
|
||||
expect($settings->whatsapp)->toBe('https://wa.me/123456789');
|
||||
expect($settings->telegram)->toBe('https://t.me/channel');
|
||||
});
|
||||
|
||||
it('validates social settings url format', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('socialForm.facebook', 'not-a-url')
|
||||
->call('updateSocial')
|
||||
->assertHasErrors([
|
||||
'socialForm.facebook' => 'url',
|
||||
]);
|
||||
});
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| SEO Settings Update
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
it('updates seo settings successfully', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('seoForm.meta_description', 'Updated meta description for SEO')
|
||||
->set('seoForm.meta_keywords', 'keyword1, keyword2, keyword3')
|
||||
->set('seoForm.meta_author', 'Updated Author')
|
||||
->set('seoForm.og_image', 'https://example.com/image.jpg')
|
||||
->set('seoForm.og_title', 'Open Graph Title')
|
||||
->set('seoForm.og_description', 'Open Graph Description')
|
||||
->set('seoForm.og_type', 'article')
|
||||
->set('seoForm.twitter_card', 'summary_large_image')
|
||||
->set('seoForm.canonical_url', 'https://example.com/page')
|
||||
->call('updateSeo')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$settings = app(SeoSettings::class);
|
||||
expect($settings->meta_description)->toBe('Updated meta description for SEO');
|
||||
expect($settings->meta_keywords)->toBe('keyword1, keyword2, keyword3');
|
||||
expect($settings->meta_author)->toBe('Updated Author');
|
||||
expect($settings->og_image)->toBe('https://example.com/image.jpg');
|
||||
expect($settings->og_title)->toBe('Open Graph Title');
|
||||
expect($settings->og_description)->toBe('Open Graph Description');
|
||||
expect($settings->og_type)->toBe('article');
|
||||
expect($settings->twitter_card)->toBe('summary_large_image');
|
||||
expect($settings->canonical_url)->toBe('https://example.com/page');
|
||||
});
|
||||
|
||||
it('validates seo settings required fields', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('seoForm.meta_description', '')
|
||||
->set('seoForm.meta_keywords', '')
|
||||
->set('seoForm.meta_author', '')
|
||||
->call('updateSeo')
|
||||
->assertHasErrors([
|
||||
'seoForm.meta_description' => 'required',
|
||||
'seoForm.meta_keywords' => 'required',
|
||||
'seoForm.meta_author' => 'required',
|
||||
]);
|
||||
});
|
||||
|
||||
it('validates seo settings og_type enum', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('seoForm.meta_description', 'Valid description')
|
||||
->set('seoForm.meta_keywords', 'keywords')
|
||||
->set('seoForm.meta_author', 'Author')
|
||||
->set('seoForm.og_type', 'invalid_type')
|
||||
->call('updateSeo')
|
||||
->assertHasErrors([
|
||||
'seoForm.og_type' => 'in',
|
||||
]);
|
||||
});
|
||||
|
||||
it('validates seo settings twitter_card enum', function () {
|
||||
mountApplicationComponent($this->user)
|
||||
->set('seoForm.meta_description', 'Valid description')
|
||||
->set('seoForm.meta_keywords', 'keywords')
|
||||
->set('seoForm.meta_author', 'Author')
|
||||
->set('seoForm.twitter_card', 'invalid_card')
|
||||
->call('updateSeo')
|
||||
->assertHasErrors([
|
||||
'seoForm.twitter_card' => 'in',
|
||||
]);
|
||||
});
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authorization Tests
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
it('requires update general settings permission', function () {
|
||||
// Temporarily remove the permission from the user
|
||||
$this->ownerRole->revokePermissionTo('update general settings');
|
||||
|
||||
mountApplicationComponent($this->user)
|
||||
->call('updateGeneral')
|
||||
->assertForbidden();
|
||||
|
||||
// Restore the permission
|
||||
$this->user->givePermissionTo('update general settings');
|
||||
});
|
||||
|
||||
it('requires update contact settings permission', function () {
|
||||
// Temporarily remove the permission from the user
|
||||
$this->ownerRole->revokePermissionTo('update contact settings');
|
||||
|
||||
mountApplicationComponent($this->user)
|
||||
->call('updateContact')
|
||||
->assertForbidden();
|
||||
|
||||
// Restore the permission
|
||||
$this->user->givePermissionTo('update contact settings');
|
||||
});
|
||||
|
||||
it('requires update social settings permission', function () {
|
||||
// Temporarily remove the permission from the user
|
||||
$this->ownerRole->revokePermissionTo('update social settings');
|
||||
|
||||
mountApplicationComponent($this->user)
|
||||
->call('updateSocial')
|
||||
->assertForbidden();
|
||||
|
||||
// Restore the permission
|
||||
$this->user->givePermissionTo('update social settings');
|
||||
});
|
||||
|
||||
it('requires update seo settings permission', function () {
|
||||
// Temporarily remove the permission from the user
|
||||
$this->ownerRole->revokePermissionTo('update seo settings');
|
||||
|
||||
mountApplicationComponent($this->user)
|
||||
->call('updateSeo')
|
||||
->assertForbidden();
|
||||
|
||||
// Restore the permission
|
||||
$this->user->givePermissionTo('update seo settings');
|
||||
});
|
||||
201
tests/Feature/Livewire/Studio/Setting/ContactFormTest.php
Normal file
201
tests/Feature/Livewire/Studio/Setting/ContactFormTest.php
Normal file
@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Forms\Studio\Setting\ContactForm;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Livewire\Livewire;
|
||||
|
||||
function createContactForm()
|
||||
{
|
||||
// Create a minimal Livewire component for testing
|
||||
$component = new class extends \Livewire\Component
|
||||
{
|
||||
public ContactForm $form;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->form = new ContactForm($this, 'form');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return '<div></div>';
|
||||
}
|
||||
};
|
||||
|
||||
$component->mount();
|
||||
|
||||
return $component->form;
|
||||
}
|
||||
|
||||
it('has correct validation rules', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
expect($rules)->toHaveKey('phone_number');
|
||||
expect($rules)->toHaveKey('email');
|
||||
expect($rules)->toHaveKey('address');
|
||||
expect($rules)->toHaveKey('map_embed');
|
||||
|
||||
expect($rules['phone_number'])->toContain('required');
|
||||
expect($rules['phone_number'])->toContain('string');
|
||||
expect($rules['phone_number'])->toContain('min:10');
|
||||
expect($rules['phone_number'])->toContain('max:20');
|
||||
|
||||
expect($rules['email'])->toContain('nullable');
|
||||
expect($rules['email'])->toContain('email');
|
||||
expect($rules['email'])->toContain('max:100');
|
||||
|
||||
expect($rules['address'])->toContain('required');
|
||||
expect($rules['address'])->toContain('string');
|
||||
expect($rules['address'])->toContain('min:10');
|
||||
expect($rules['address'])->toContain('max:500');
|
||||
|
||||
expect($rules['map_embed'])->toContain('nullable');
|
||||
expect($rules['map_embed'])->toContain('string');
|
||||
expect($rules['map_embed'])->toContain('max:2000');
|
||||
});
|
||||
|
||||
it('validates required fields', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'phone_number' => '',
|
||||
'address' => '',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('phone_number'))->toBeTrue();
|
||||
expect($validator->errors()->has('address'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates phone number format', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'phone_number' => 'invalid',
|
||||
'address' => 'Valid Address',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('phone_number'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates email format', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'phone_number' => '0812 3456 789',
|
||||
'email' => 'invalid-email',
|
||||
'address' => 'Valid Address',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('email'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates phone number length', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'phone_number' => '123',
|
||||
'address' => 'Valid Address',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('phone_number'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates address length', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'phone_number' => '+628123456789',
|
||||
'address' => 'Short',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('address'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates email max length', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'phone_number' => '+628123456789',
|
||||
'email' => str_repeat('a', 101).'@example.com',
|
||||
'address' => 'Valid Address',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('email'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates map embed max length', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'phone_number' => '+628123456789',
|
||||
'address' => 'Valid Address',
|
||||
'map_embed' => str_repeat('a', 2001),
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('map_embed'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('accepts nullable email', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'phone_number' => '0812 3456 789',
|
||||
'email' => null,
|
||||
'address' => 'Valid Address',
|
||||
], $rules);
|
||||
|
||||
expect($validator->passes())->toBeTrue();
|
||||
});
|
||||
|
||||
it('accepts nullable map embed', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'phone_number' => '0812 3456 789',
|
||||
'address' => 'Valid Address',
|
||||
'map_embed' => null,
|
||||
], $rules);
|
||||
|
||||
expect($validator->passes())->toBeTrue();
|
||||
});
|
||||
|
||||
it('passes validation with valid data', function () {
|
||||
$form = createContactForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'phone_number' => '0812 3456 789',
|
||||
'email' => 'test@example.com',
|
||||
'address' => 'Valid Address with proper length',
|
||||
'map_embed' => '<iframe>valid embed</iframe>',
|
||||
], $rules);
|
||||
|
||||
expect($validator->passes())->toBeTrue();
|
||||
});
|
||||
|
||||
it('has correct validation attributes', function () {
|
||||
$form = createContactForm();
|
||||
$attributes = $form->validationAttributes();
|
||||
|
||||
expect($attributes)->toHaveKey('phone_number', 'nomor telepon');
|
||||
expect($attributes)->toHaveKey('email', 'email');
|
||||
expect($attributes)->toHaveKey('address', 'alamat');
|
||||
expect($attributes)->toHaveKey('map_embed', 'embed peta');
|
||||
});
|
||||
143
tests/Feature/Livewire/Studio/Setting/GeneralFormTest.php
Normal file
143
tests/Feature/Livewire/Studio/Setting/GeneralFormTest.php
Normal file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Forms\Studio\Setting\GeneralForm;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Livewire\Livewire;
|
||||
|
||||
function createGeneralForm()
|
||||
{
|
||||
// Create a minimal Livewire component for testing
|
||||
$component = new class extends \Livewire\Component
|
||||
{
|
||||
public GeneralForm $form;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->form = new GeneralForm($this, 'form');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return '<div></div>';
|
||||
}
|
||||
};
|
||||
|
||||
$component->mount();
|
||||
|
||||
return $component->form;
|
||||
}
|
||||
|
||||
it('has correct validation rules', function () {
|
||||
$form = createGeneralForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
expect($rules)->toHaveKey('site_name');
|
||||
expect($rules)->toHaveKey('site_tagline');
|
||||
expect($rules)->toHaveKey('site_description');
|
||||
expect($rules)->toHaveKey('maintenance_mode');
|
||||
|
||||
expect($rules['site_name'])->toContain('required');
|
||||
expect($rules['site_name'])->toContain('string');
|
||||
expect($rules['site_name'])->toContain('max:100');
|
||||
expect($rules['site_name'])->toContain('min:1');
|
||||
|
||||
expect($rules['site_tagline'])->toContain('required');
|
||||
expect($rules['site_tagline'])->toContain('string');
|
||||
expect($rules['site_tagline'])->toContain('max:150');
|
||||
expect($rules['site_tagline'])->toContain('min:1');
|
||||
|
||||
expect($rules['site_description'])->toContain('required');
|
||||
expect($rules['site_description'])->toContain('string');
|
||||
expect($rules['site_description'])->toContain('min:10');
|
||||
expect($rules['site_description'])->toContain('max:500');
|
||||
|
||||
expect($rules['maintenance_mode'])->toContain('required');
|
||||
expect($rules['maintenance_mode'])->toContain('boolean');
|
||||
});
|
||||
|
||||
it('validates required fields', function () {
|
||||
$form = createGeneralForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'site_name' => '',
|
||||
'site_tagline' => '',
|
||||
'site_description' => '',
|
||||
'maintenance_mode' => false,
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('site_name'))->toBeTrue();
|
||||
expect($validator->errors()->has('site_tagline'))->toBeTrue();
|
||||
expect($validator->errors()->has('site_description'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates minimum lengths', function () {
|
||||
$form = createGeneralForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'site_name' => 'A',
|
||||
'site_tagline' => 'B',
|
||||
'site_description' => 'Short',
|
||||
'maintenance_mode' => false,
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('site_description'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates maximum lengths', function () {
|
||||
$form = createGeneralForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'site_name' => str_repeat('A', 101),
|
||||
'site_tagline' => str_repeat('B', 151),
|
||||
'site_description' => 'Valid description',
|
||||
'maintenance_mode' => false,
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('site_name'))->toBeTrue();
|
||||
expect($validator->errors()->has('site_tagline'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates maintenance mode boolean', function () {
|
||||
$form = createGeneralForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'site_name' => 'Valid Name',
|
||||
'site_tagline' => 'Valid Tagline',
|
||||
'site_description' => 'Valid description with proper length',
|
||||
'maintenance_mode' => 'not_boolean',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('maintenance_mode'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('passes validation with valid data', function () {
|
||||
$form = createGeneralForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'site_name' => 'Valid Site Name',
|
||||
'site_tagline' => 'Valid Tagline',
|
||||
'site_description' => 'Valid description with proper length for the site',
|
||||
'maintenance_mode' => true,
|
||||
], $rules);
|
||||
|
||||
expect($validator->passes())->toBeTrue();
|
||||
});
|
||||
|
||||
it('has correct validation attributes', function () {
|
||||
$form = createGeneralForm();
|
||||
$attributes = $form->validationAttributes();
|
||||
|
||||
expect($attributes)->toHaveKey('site_name', 'nama situs');
|
||||
expect($attributes)->toHaveKey('site_tagline', 'tagline situs');
|
||||
expect($attributes)->toHaveKey('site_description', 'deskripsi situs');
|
||||
expect($attributes)->toHaveKey('maintenance_mode', 'mode maintenance');
|
||||
});
|
||||
350
tests/Feature/Livewire/Studio/Setting/SeoFormTest.php
Normal file
350
tests/Feature/Livewire/Studio/Setting/SeoFormTest.php
Normal file
@ -0,0 +1,350 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Forms\Studio\Setting\SeoForm;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Livewire\Livewire;
|
||||
|
||||
function createSeoForm()
|
||||
{
|
||||
// Create a minimal Livewire component for testing
|
||||
$component = new class extends \Livewire\Component
|
||||
{
|
||||
public SeoForm $form;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->form = new SeoForm($this, 'form');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return '<div></div>';
|
||||
}
|
||||
};
|
||||
|
||||
$component->mount();
|
||||
|
||||
return $component->form;
|
||||
}
|
||||
|
||||
it('has correct validation rules', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
expect($rules)->toHaveKey('meta_description');
|
||||
expect($rules)->toHaveKey('meta_keywords');
|
||||
expect($rules)->toHaveKey('meta_author');
|
||||
expect($rules)->toHaveKey('og_image');
|
||||
expect($rules)->toHaveKey('og_title');
|
||||
expect($rules)->toHaveKey('og_description');
|
||||
expect($rules)->toHaveKey('og_type');
|
||||
expect($rules)->toHaveKey('twitter_card');
|
||||
expect($rules)->toHaveKey('canonical_url');
|
||||
|
||||
expect($rules['meta_description'])->toContain('required');
|
||||
expect($rules['meta_description'])->toContain('string');
|
||||
expect($rules['meta_description'])->toContain('min:10');
|
||||
expect($rules['meta_description'])->toContain('max:160');
|
||||
|
||||
expect($rules['meta_keywords'])->toContain('required');
|
||||
expect($rules['meta_keywords'])->toContain('string');
|
||||
expect($rules['meta_keywords'])->toContain('min:3');
|
||||
expect($rules['meta_keywords'])->toContain('max:255');
|
||||
|
||||
expect($rules['meta_author'])->toContain('required');
|
||||
expect($rules['meta_author'])->toContain('string');
|
||||
expect($rules['meta_author'])->toContain('min:1');
|
||||
expect($rules['meta_author'])->toContain('max:150');
|
||||
|
||||
expect($rules['og_image'])->toContain('nullable');
|
||||
expect($rules['og_image'])->toContain('string');
|
||||
expect($rules['og_image'])->toContain('max:500');
|
||||
expect($rules['og_image'])->toContain('url');
|
||||
|
||||
expect($rules['og_title'])->toContain('nullable');
|
||||
expect($rules['og_title'])->toContain('string');
|
||||
expect($rules['og_title'])->toContain('max:255');
|
||||
|
||||
expect($rules['og_description'])->toContain('nullable');
|
||||
expect($rules['og_description'])->toContain('string');
|
||||
expect($rules['og_description'])->toContain('max:300');
|
||||
|
||||
expect($rules['og_type'])->toContain('nullable');
|
||||
expect($rules['og_type'])->toContain('string');
|
||||
expect($rules['og_type'])->toContain('max:50');
|
||||
expect($rules['og_type'])->toContain('in:website,article,product');
|
||||
|
||||
expect($rules['twitter_card'])->toContain('nullable');
|
||||
expect($rules['twitter_card'])->toContain('string');
|
||||
expect($rules['twitter_card'])->toContain('max:50');
|
||||
expect($rules['twitter_card'])->toContain('in:summary,summary_large_image');
|
||||
|
||||
expect($rules['canonical_url'])->toContain('nullable');
|
||||
expect($rules['canonical_url'])->toContain('string');
|
||||
expect($rules['canonical_url'])->toContain('max:500');
|
||||
expect($rules['canonical_url'])->toContain('url');
|
||||
});
|
||||
|
||||
it('validates required fields', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => '',
|
||||
'meta_keywords' => '',
|
||||
'meta_author' => '',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('meta_description'))->toBeTrue();
|
||||
expect($validator->errors()->has('meta_keywords'))->toBeTrue();
|
||||
expect($validator->errors()->has('meta_author'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates meta description length', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Short',
|
||||
'meta_keywords' => 'keywords',
|
||||
'meta_author' => 'Author',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('meta_description'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates meta description max length', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => str_repeat('a', 161),
|
||||
'meta_keywords' => 'keywords',
|
||||
'meta_author' => 'Author',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('meta_description'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates meta keywords minimum length', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'ab',
|
||||
'meta_author' => 'Author',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('meta_keywords'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates meta author max length', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => str_repeat('a', 151),
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('meta_author'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates og_image url format and max length', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => 'Author',
|
||||
'og_image' => 'not-a-url',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('og_image'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates og_image max length', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => 'Author',
|
||||
'og_image' => 'https://example.com/'.str_repeat('a', 501),
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('og_image'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates og_title max length', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => 'Author',
|
||||
'og_title' => str_repeat('a', 256),
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('og_title'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates og_description max length', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => 'Author',
|
||||
'og_description' => str_repeat('a', 301),
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('og_description'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates og_type enum values', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => 'Author',
|
||||
'og_type' => 'invalid_type',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('og_type'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('accepts valid og_type values', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
$validTypes = ['website', 'article', 'product'];
|
||||
|
||||
foreach ($validTypes as $type) {
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => 'Author',
|
||||
'og_type' => $type,
|
||||
], $rules);
|
||||
|
||||
expect($validator->passes())->toBeTrue();
|
||||
}
|
||||
});
|
||||
|
||||
it('validates twitter_card enum values', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => 'Author',
|
||||
'twitter_card' => 'invalid_card',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('twitter_card'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('accepts valid twitter_card values', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
$validCards = ['summary', 'summary_large_image'];
|
||||
|
||||
foreach ($validCards as $card) {
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => 'Author',
|
||||
'twitter_card' => $card,
|
||||
], $rules);
|
||||
|
||||
expect($validator->passes())->toBeTrue();
|
||||
}
|
||||
});
|
||||
|
||||
it('validates canonical_url url format and max length', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => 'Author',
|
||||
'canonical_url' => 'not-a-url',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('canonical_url'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('accepts nullable fields', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description with proper length',
|
||||
'meta_keywords' => 'valid keywords',
|
||||
'meta_author' => 'Author',
|
||||
'og_image' => null,
|
||||
'og_title' => null,
|
||||
'og_description' => null,
|
||||
'og_type' => null,
|
||||
'twitter_card' => null,
|
||||
'canonical_url' => null,
|
||||
], $rules);
|
||||
|
||||
expect($validator->passes())->toBeTrue();
|
||||
});
|
||||
|
||||
it('passes validation with valid data', function () {
|
||||
$form = createSeoForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'meta_description' => 'Valid meta description for SEO purposes',
|
||||
'meta_keywords' => 'keyword1, keyword2, keyword3',
|
||||
'meta_author' => 'Valid Author',
|
||||
'og_image' => 'https://example.com/image.jpg',
|
||||
'og_title' => 'Valid OG Title',
|
||||
'og_description' => 'Valid OG Description',
|
||||
'og_type' => 'article',
|
||||
'twitter_card' => 'summary_large_image',
|
||||
'canonical_url' => 'https://example.com/page',
|
||||
], $rules);
|
||||
|
||||
expect($validator->passes())->toBeTrue();
|
||||
});
|
||||
|
||||
it('has correct validation attributes', function () {
|
||||
$form = createSeoForm();
|
||||
$attributes = $form->validationAttributes();
|
||||
|
||||
expect($attributes)->toHaveKey('meta_description', 'meta deskripsi');
|
||||
expect($attributes)->toHaveKey('meta_keywords', 'meta kata kunci');
|
||||
expect($attributes)->toHaveKey('meta_author', 'meta penulis');
|
||||
expect($attributes)->toHaveKey('og_image', 'gambar Open Graph');
|
||||
expect($attributes)->toHaveKey('og_title', 'judul Open Graph');
|
||||
expect($attributes)->toHaveKey('og_description', 'deskripsi Open Graph');
|
||||
expect($attributes)->toHaveKey('og_type', 'tipe Open Graph');
|
||||
expect($attributes)->toHaveKey('twitter_card', 'kartu Twitter');
|
||||
expect($attributes)->toHaveKey('canonical_url', 'URL kanonis');
|
||||
});
|
||||
117
tests/Feature/Livewire/Studio/Setting/SocialFormTest.php
Normal file
117
tests/Feature/Livewire/Studio/Setting/SocialFormTest.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Forms\Studio\Setting\SocialForm;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Livewire\Livewire;
|
||||
|
||||
function createSocialForm()
|
||||
{
|
||||
// Create a minimal Livewire component for testing
|
||||
$component = new class extends \Livewire\Component
|
||||
{
|
||||
public SocialForm $form;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->form = new SocialForm($this, 'form');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return '<div></div>';
|
||||
}
|
||||
};
|
||||
|
||||
$component->mount();
|
||||
|
||||
return $component->form;
|
||||
}
|
||||
|
||||
it('has correct validation rules', function () {
|
||||
$form = createSocialForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
expect($rules)->toHaveKey('facebook');
|
||||
expect($rules)->toHaveKey('instagram');
|
||||
expect($rules)->toHaveKey('youtube');
|
||||
expect($rules)->toHaveKey('tiktok');
|
||||
expect($rules)->toHaveKey('whatsapp');
|
||||
expect($rules)->toHaveKey('telegram');
|
||||
|
||||
foreach (['facebook', 'instagram', 'youtube', 'tiktok', 'whatsapp', 'telegram'] as $field) {
|
||||
expect($rules[$field])->toContain('nullable');
|
||||
expect($rules[$field])->toContain('url');
|
||||
expect($rules[$field])->toContain('max:255');
|
||||
}
|
||||
});
|
||||
|
||||
it('validates nullable fields accept null values', function () {
|
||||
$form = createSocialForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'facebook' => null,
|
||||
'instagram' => null,
|
||||
'youtube' => null,
|
||||
'tiktok' => null,
|
||||
'whatsapp' => null,
|
||||
'telegram' => null,
|
||||
], $rules);
|
||||
|
||||
expect($validator->passes())->toBeTrue();
|
||||
});
|
||||
|
||||
it('validates url format for social media fields', function () {
|
||||
$form = createSocialForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'facebook' => 'not-a-url',
|
||||
'instagram' => 'https://instagram.com/valid',
|
||||
'youtube' => 'invalid-url',
|
||||
'tiktok' => 'https://tiktok.com/@valid',
|
||||
'whatsapp' => 'not-a-url',
|
||||
'telegram' => 'https://t.me/valid',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('facebook'))->toBeTrue();
|
||||
expect($validator->errors()->has('youtube'))->toBeTrue();
|
||||
expect($validator->errors()->has('whatsapp'))->toBeTrue();
|
||||
expect($validator->errors()->has('instagram'))->toBeFalse();
|
||||
expect($validator->errors()->has('tiktok'))->toBeFalse();
|
||||
expect($validator->errors()->has('telegram'))->toBeFalse();
|
||||
});
|
||||
|
||||
it('validates url max length', function () {
|
||||
$form = createSocialForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'facebook' => 'https://facebook.com/'.str_repeat('a', 256),
|
||||
'instagram' => 'https://instagram.com/valid',
|
||||
'youtube' => 'https://youtube.com/valid',
|
||||
'tiktok' => 'https://tiktok.com/@valid',
|
||||
'whatsapp' => 'https://wa.me/valid',
|
||||
'telegram' => 'https://t.me/valid',
|
||||
], $rules);
|
||||
|
||||
expect($validator->fails())->toBeTrue();
|
||||
expect($validator->errors()->has('facebook'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('accepts valid urls', function () {
|
||||
$form = createSocialForm();
|
||||
$rules = $form->rules();
|
||||
|
||||
$validator = Validator::make([
|
||||
'facebook' => 'https://facebook.com/page',
|
||||
'instagram' => 'https://instagram.com/page',
|
||||
'youtube' => 'https://youtube.com/channel',
|
||||
'tiktok' => 'https://tiktok.com/@user',
|
||||
'whatsapp' => 'https://wa.me/123456789',
|
||||
'telegram' => 'https://t.me/channel',
|
||||
], $rules);
|
||||
|
||||
expect($validator->passes())->toBeTrue();
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user