setupUser(); $role = Role::firstOrCreate(['name' => 'Owner']); Permission::firstOrCreate(['name' => 'view broadcast']); Permission::firstOrCreate(['name' => 'create broadcast']); Permission::firstOrCreate(['name' => 'delete broadcast']); $role->givePermissionTo(['view broadcast', 'create broadcast', 'delete broadcast']); $this->user->assignRole($role); // Create additional roles for testing $this->customerRole = Role::firstOrCreate(['name' => 'Customer']); $this->employeeRole = Role::firstOrCreate(['name' => 'Employee']); $this->developerRole = Role::firstOrCreate(['name' => 'Developer']); }); it('renders the broadcast page correctly', function () { $this->actingAs($this->user) ->get(route('studio.information.broadcast.index')) ->assertOk() ->assertSeeLivewire(Broadcast::class); }); it('can open create modal', function () { Livewire::actingAs($this->user) ->test(Broadcast::class) ->dispatch('modal:open', method: 'create', modalTitle: 'Tambah Broadcast') ->assertSet('method', 'create') ->assertSet('modalTitle', 'Tambah Broadcast'); }); it('validates required fields on create', function () { Livewire::actingAs($this->user) ->test(Broadcast::class) ->call('create') ->assertHasErrors([ 'form.title' => 'required', 'form.body' => 'required', 'form.role_ids' => 'required', ]); }); it('validates title max length', function () { Livewire::actingAs($this->user) ->test(Broadcast::class) ->set('form.title', str_repeat('a', 31)) ->set('form.body', 'Test Body') ->set('form.role_ids', [$this->customerRole->id]) ->call('create') ->assertHasErrors(['form.title' => 'max']); }); it('validates body max length', function () { Livewire::actingAs($this->user) ->test(Broadcast::class) ->set('form.title', 'Test Title') ->set('form.body', str_repeat('a', 51)) ->set('form.role_ids', [$this->customerRole->id]) ->call('create') ->assertHasErrors(['form.body' => 'max']); }); it('validates link must be valid url', function () { Livewire::actingAs($this->user) ->test(Broadcast::class) ->set('form.title', 'Test Title') ->set('form.body', 'Test Body') ->set('form.link', 'not-a-valid-url') ->set('form.role_ids', [$this->customerRole->id]) ->call('create') ->assertHasErrors(['form.link' => 'url']); }); it('validates role_ids must be array with at least one item', function () { Livewire::actingAs($this->user) ->test(Broadcast::class) ->set('form.title', 'Test Title') ->set('form.body', 'Test Body') ->set('form.role_ids', []) ->call('create') ->assertHasErrors(['form.role_ids' => 'required']); }); it('can store a new broadcast', function () { Queue::fake(); Livewire::actingAs($this->user) ->test(Broadcast::class) ->set('form.title', 'Broadcast Baru') ->set('form.body', 'Ini adalah broadcast baru') ->set('form.link', 'https://example.com') ->set('form.role_ids', [$this->customerRole->id]) ->call('create') ->assertHasNoErrors() ->assertDispatched('refreshDatatable'); $this->assertDatabaseHas('broadcasts', [ 'user_id' => $this->user->id, 'title' => 'Broadcast Baru', 'body' => 'Ini adalah broadcast baru', 'link' => 'https://example.com', ]); $broadcast = BroadcastModel::where('title', 'Broadcast Baru')->first(); $this->assertDatabaseHas('broadcast_audiences', [ 'broadcast_id' => $broadcast->id, 'audience_id' => $this->customerRole->id, ]); }); it('can store broadcast without link', function () { Queue::fake(); Livewire::actingAs($this->user) ->test(Broadcast::class) ->set('form.title', 'Broadcast Tanpa Link') ->set('form.body', 'Broadcast ini tidak memiliki link') ->set('form.role_ids', [$this->employeeRole->id]) ->call('create') ->assertHasNoErrors() ->assertDispatched('refreshDatatable'); $this->assertDatabaseHas('broadcasts', [ 'title' => 'Broadcast Tanpa Link', 'body' => 'Broadcast ini tidak memiliki link', 'link' => null, ]); }); it('can store broadcast with multiple audiences', function () { Queue::fake(); Livewire::actingAs($this->user) ->test(Broadcast::class) ->set('form.title', 'Multi Audience') ->set('form.body', 'Broadcast untuk banyak role') ->set('form.role_ids', [$this->customerRole->id, $this->employeeRole->id]) ->call('create') ->assertHasNoErrors() ->assertDispatched('refreshDatatable'); $broadcast = BroadcastModel::where('title', 'Multi Audience')->first(); expect($broadcast->audiences)->toHaveCount(2); }); it('can delete a broadcast', function () { $broadcast = BroadcastModel::factory()->create([ 'user_id' => $this->user->id, ]); Livewire::actingAs($this->user) ->test(Broadcast::class) ->call('delete', $broadcast) ->assertDispatched('refreshDatatable'); $this->assertDatabaseMissing('broadcasts', ['id' => $broadcast->id]); }); it('cannot access broadcast page without permission', function () { $this->user->roles()->detach(); $this->user->permissions()->detach(); $this->actingAs($this->user) ->get(route('studio.information.broadcast.index')) ->assertForbidden(); }); it('cannot create broadcast without permission', function () { $this->user->roles()->detach(); $this->user->permissions()->detach(); Livewire::actingAs($this->user) ->test(Broadcast::class) ->set('form.title', 'Test') ->set('form.body', 'Test') ->set('form.role_ids', [$this->customerRole->id]) ->call('create') ->assertForbidden(); }); it('cannot delete broadcast without permission', function () { $broadcast = BroadcastModel::factory()->create(); $this->user->roles()->detach(); $this->user->permissions()->detach(); Livewire::actingAs($this->user) ->test(Broadcast::class) ->call('delete', $broadcast) ->assertForbidden(); });