setupUser(); $role = Role::firstOrCreate(['name' => 'Owner']); Permission::firstOrCreate(['name' => 'view payroll']); Permission::firstOrCreate(['name' => 'manage adjustment']); $role->givePermissionTo(['view payroll', 'manage adjustment']); $this->user->assignRole($role); }); it('renders the payroll page correctly', function () { PayrollModel::factory()->create([ 'user_id' => $this->user->id, 'period_month' => Carbon::now()->format('Y-m'), 'is_paid' => \App\Enums\IsPaid::NOT_PAID, ]); $this->actingAs($this->user) ->get(route('studio.finance.payroll.index')) ->assertOk() ->assertSeeLivewire(Payroll::class); }); it('can open modal for adjustment', function () { Livewire::actingAs($this->user) ->test(Payroll::class) ->call('openModal', 'create', 'Tambah Penyesuaian') ->assertSet('method', 'create') ->assertSet('modalTitle', 'Tambah Penyesuaian'); }); it('shows validation errors on adjustment form', function () { Livewire::actingAs($this->user) ->test(Payroll::class) ->call('create') ->assertHasErrors([ 'form.user_ids' => 'required', 'form.type' => 'required', 'form.amount' => 'required', 'form.description' => 'required', ]); }); it('can add a bonus adjustment', function () { $employeeUser = User::factory()->active()->create(); Employee::factory()->create(['user_id' => $employeeUser->id, 'base_salary' => 5000000]); // Create payroll for the current month $payroll = PayrollModel::factory()->create([ 'user_id' => $employeeUser->id, 'period_month' => Carbon::now()->format('Y-m'), 'base_salary' => 5000000, 'bonus' => 0, 'deduction' => 0, 'total_salary' => 5000000, ]); Livewire::actingAs($this->user) ->test(Payroll::class) ->set('form.user_ids', [$employeeUser->id]) ->set('form.type', SalaryAdjustmentType::BONUS->value) ->set('form.amount', '500000') ->set('form.description', 'Bonus Performance') ->call('create') ->assertHasNoErrors() ->assertDispatched('refreshDatatable'); $payroll->refresh(); expect($payroll->bonus)->toBe(500000); expect($payroll->total_salary)->toBe(5500000); $this->assertDatabaseHas('payroll_adjustments', [ 'payroll_id' => $payroll->id, 'type' => SalaryAdjustmentType::BONUS->value, 'amount' => 500000, 'description' => 'Bonus Performance', ]); }); it('can add a deduction adjustment', function () { $employeeUser = User::factory()->active()->create(); Employee::factory()->create(['user_id' => $employeeUser->id, 'base_salary' => 5000000]); // Create payroll for the current month $payroll = PayrollModel::factory()->create([ 'user_id' => $employeeUser->id, 'period_month' => Carbon::now()->format('Y-m'), 'base_salary' => 5000000, 'bonus' => 0, 'deduction' => 0, 'total_salary' => 5000000, ]); Livewire::actingAs($this->user) ->test(Payroll::class) ->set('form.user_ids', [$employeeUser->id]) ->set('form.type', SalaryAdjustmentType::DEDUCTION->value) ->set('form.amount', '200000') ->set('form.description', 'Potongan Keterlambatan') ->call('create') ->assertHasNoErrors() ->assertDispatched('refreshDatatable'); $payroll->refresh(); expect($payroll->deduction)->toBe(200000); expect($payroll->total_salary)->toBe(4800000); }); it('can delete an adjustment', function () { $employeeUser = User::factory()->active()->create(); Employee::factory()->create(['user_id' => $employeeUser->id, 'base_salary' => 5000000]); $payroll = PayrollModel::factory()->create([ 'user_id' => $employeeUser->id, 'period_month' => Carbon::now()->format('Y-m'), 'base_salary' => 5000000, 'bonus' => 500000, 'deduction' => 0, 'total_salary' => 5500000, ]); $adjustment = PayrollAdjustment::factory()->create([ 'payroll_id' => $payroll->id, 'type' => SalaryAdjustmentType::BONUS, 'amount' => 500000, ]); Livewire::actingAs($this->user) ->test(Payroll::class) ->call('delete', $adjustment->id) ->assertHasNoErrors() ->assertDispatched('refreshDatatable'); $payroll->refresh(); expect($payroll->bonus)->toBe(0); expect($payroll->total_salary)->toBe(5000000); $this->assertSoftDeleted('payroll_adjustments', ['id' => $adjustment->id]); }); it('can export payroll as pdf', function () { $employeeUser = User::factory()->active()->create(); Employee::factory()->create(['user_id' => $employeeUser->id, 'base_salary' => 5000000]); $payroll = PayrollModel::factory()->create([ 'user_id' => $employeeUser->id, 'period_month' => Carbon::now()->format('Y-m'), 'base_salary' => 5000000, 'is_paid' => IsPaid::NOT_PAID, ]); Livewire::actingAs($this->user) ->test(Payroll::class) ->call('exportPdf', $payroll) ->assertFileDownloaded(); }); it('cannot manage adjustment without permission', function () { $this->user->roles()->detach(); $this->user->permissions()->detach(); Livewire::actingAs($this->user) ->test(Payroll::class) ->call('create') ->assertForbidden(); }); it('cannot access payroll page without permission', function () { $this->user->roles()->detach(); $this->user->permissions()->detach(); $this->actingAs($this->user) ->get(route('studio.finance.payroll.index')) ->assertForbidden(); });