setupUser(); $role = Role::firstOrCreate(['name' => 'Owner']); Permission::firstOrCreate(['name' => 'view reward']); Permission::firstOrCreate(['name' => 'create reward']); Permission::firstOrCreate(['name' => 'update reward']); Permission::firstOrCreate(['name' => 'delete reward']); $role->givePermissionTo(['view reward', 'create reward', 'update reward', 'delete reward']); $this->user->assignRole($role); }); it('renders the reward page correctly', function () { $this->actingAs($this->user) ->get(route('studio.loyalty.reward.index')) ->assertOk() ->assertSeeLivewire(Reward::class); }); it('can open create modal', function () { Livewire::actingAs($this->user) ->test(Reward::class) ->call('openModal', 'create', 'Tambah Hadiah') ->assertSet('method', 'create') ->assertSet('modalTitle', 'Tambah Hadiah'); }); it('shows validation errors on create', function () { Livewire::actingAs($this->user) ->test(Reward::class) ->call('create') ->assertHasErrors([ 'form.name' => 'required', 'form.points' => 'required', 'form.start_date' => 'required', 'form.tier_ids' => 'required', ]); }); it('can store a new reward', function () { $tier = Tier::factory()->create(['min_spending' => 0]); Livewire::actingAs($this->user) ->test(Reward::class) ->set('form.name', 'Hadiah Keren') ->set('form.points', '100') ->set('form.category', RewardCategory::REGULAR->value) ->set('form.is_show', IsShow::SHOW->value) ->set('form.start_date', now()->format('Y-m-d')) ->set('form.tier_ids', [$tier->id]) ->call('create') ->assertHasNoErrors() ->assertDispatched('refreshDatatable'); $this->assertDatabaseHas('rewards', [ 'name' => 'Hadiah Keren', 'points' => 100, ]); }); it('can open edit modal and load data', function () { $tier = Tier::factory()->create(['min_spending' => 0]); $reward = RewardModel::factory()->create(['name' => 'Old Name', 'points' => 50]); $reward->tiers()->attach($tier); Livewire::actingAs($this->user) ->test(Reward::class) ->call('openModal', 'update', 'Ubah Hadiah', $reward->hash_id) ->set('form.reward', $reward) ->set('form.name', 'Old Name') ->set('form.points', '50') ->assertSet('method', 'update') ->assertSet('form.name', 'Old Name') ->assertSet('form.points', '50'); }); it('can update a reward', function () { $tier = Tier::factory()->create(['min_spending' => 0]); $reward = RewardModel::factory()->create(['name' => 'Old Name', 'points' => 50]); $reward->tiers()->attach($tier); Livewire::actingAs($this->user) ->test(Reward::class) ->call('openModal', 'update', 'Ubah Hadiah', $reward->hash_id) ->set('form.reward', $reward) ->set('form.name', 'Updated Name') ->set('form.points', '75') ->set('form.category', $reward->category->value) ->set('form.is_show', $reward->is_show->value) ->set('form.start_date', $reward->start_date) ->set('form.tier_ids', [$tier->id]) ->call('update') ->assertHasNoErrors() ->assertDispatched('refreshDatatable'); $this->assertDatabaseHas('rewards', [ 'id' => $reward->id, 'name' => 'Updated Name', 'points' => 75, ]); }); it('cannot update a reward if redemptions exist', function () { $reward = RewardModel::factory()->create(); Redemption::factory()->create(['reward_id' => $reward->id]); Livewire::actingAs($this->user) ->test(Reward::class) ->call('openModal', 'update', 'Ubah Hadiah', $reward->hash_id) ->set('form.reward', $reward) ->set('form.name', 'Attempt Update') ->call('update') ->assertHasNoErrors(); // Verify it didn't change in DB $this->assertDatabaseMissing('rewards', ['id' => $reward->id, 'name' => 'Attempt Update']); }); it('can delete a reward', function () { $reward = RewardModel::factory()->create(); Livewire::actingAs($this->user) ->test(Reward::class) ->call('delete', $reward->id) ->assertHasNoErrors() ->assertDispatched('refreshDatatable'); $this->assertSoftDeleted('rewards', ['id' => $reward->id]); }); it('cannot access reward page without permission', function () { $this->user->roles()->detach(); $this->user->permissions()->detach(); $this->actingAs($this->user) ->get(route('studio.loyalty.reward.index')) ->assertForbidden(); });