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', '') ->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(''); }); 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'); });