167 lines
5.3 KiB
PHP
167 lines
5.3 KiB
PHP
<?php
|
|
|
|
use App\Enums\ExpenseType;
|
|
use App\Livewire\Studio\Finance\Expense;
|
|
use App\Models\Expense as ExpenseModel;
|
|
use App\Models\Outlet;
|
|
use Livewire\Livewire;
|
|
use Spatie\Permission\Models\Permission;
|
|
use Spatie\Permission\Models\Role;
|
|
|
|
beforeEach(function () {
|
|
$this->setupUser();
|
|
|
|
$role = Role::firstOrCreate(['name' => 'Owner']);
|
|
Permission::firstOrCreate(['name' => 'view expense']);
|
|
Permission::firstOrCreate(['name' => 'create expense']);
|
|
Permission::firstOrCreate(['name' => 'update expense']);
|
|
Permission::firstOrCreate(['name' => 'delete expense']);
|
|
$role->givePermissionTo(['view expense', 'create expense', 'update expense', 'delete expense']);
|
|
$this->user->assignRole($role);
|
|
});
|
|
|
|
it('renders the expense page correctly', function () {
|
|
$this->actingAs($this->user)
|
|
->get(route('studio.finance.expense.index'))
|
|
->assertOk()
|
|
->assertSeeLivewire(Expense::class);
|
|
});
|
|
|
|
it('can open create modal', function () {
|
|
Livewire::actingAs($this->user)
|
|
->test(Expense::class)
|
|
->call('openModal', 'create', 'Tambah Pengeluaran')
|
|
->assertSet('method', 'create')
|
|
->assertSet('modalTitle', 'Tambah Pengeluaran');
|
|
});
|
|
|
|
it('shows validation errors on create', function () {
|
|
Livewire::actingAs($this->user)
|
|
->test(Expense::class)
|
|
->call('create')
|
|
->assertHasErrors([
|
|
'form.description' => 'required',
|
|
'form.amount' => 'required',
|
|
]);
|
|
});
|
|
|
|
it('can store a new expense with single outlet', function () {
|
|
// User has 1 outlet from setupUser()
|
|
expect($this->user->outlets()->count())->toBe(1);
|
|
|
|
Livewire::actingAs($this->user)
|
|
->test(Expense::class)
|
|
->set('form.description', 'Beli Sabun')
|
|
->set('form.amount', '15000')
|
|
->call('create')
|
|
->assertHasNoErrors()
|
|
->assertDispatched('refreshDatatable');
|
|
|
|
$this->assertDatabaseHas('expenses', [
|
|
'description' => 'Beli Sabun',
|
|
'amount' => 15000,
|
|
'outlet_id' => $this->outlet->id,
|
|
'user_id' => $this->user->id,
|
|
'type' => ExpenseType::OPERATIONAL->value,
|
|
]);
|
|
});
|
|
|
|
it('requires outlet_id if user has multiple outlets', function () {
|
|
$anotherOutlet = Outlet::factory()->create();
|
|
$this->user->outlets()->attach($anotherOutlet);
|
|
|
|
Livewire::actingAs($this->user)
|
|
->test(Expense::class)
|
|
->set('form.description', 'Beli Tissue')
|
|
->set('form.amount', '10000')
|
|
// form.outlet_id is empty
|
|
->call('create')
|
|
->assertHasErrors(['form.outlet_id' => 'required']);
|
|
});
|
|
|
|
it('can store a new expense with multiple outlets', function () {
|
|
$anotherOutlet = Outlet::factory()->create();
|
|
$this->user->outlets()->attach($anotherOutlet);
|
|
|
|
Livewire::actingAs($this->user)
|
|
->test(Expense::class)
|
|
->set('form.description', 'Beli Tissue')
|
|
->set('form.amount', '10000')
|
|
->set('form.outlet_id', $anotherOutlet->id)
|
|
->call('create')
|
|
->assertHasNoErrors()
|
|
->assertDispatched('refreshDatatable');
|
|
|
|
$this->assertDatabaseHas('expenses', [
|
|
'description' => 'Beli Tissue',
|
|
'amount' => 10000,
|
|
'outlet_id' => $anotherOutlet->id,
|
|
]);
|
|
});
|
|
|
|
it('can open edit modal and load data', function () {
|
|
$expense = ExpenseModel::factory()->operational()->create([
|
|
'description' => 'Old Description',
|
|
'amount' => 50000,
|
|
'outlet_id' => $this->outlet->id,
|
|
'user_id' => $this->user->id,
|
|
]);
|
|
|
|
Livewire::actingAs($this->user)
|
|
->test(Expense::class)
|
|
->call('openModal', 'update', 'Ubah Pengeluaran', $expense->hash_id)
|
|
->set('form.expense', $expense)
|
|
->set('form.description', 'Old Description')
|
|
->set('form.amount', '50.000')
|
|
->assertSet('method', 'update')
|
|
->assertSet('form.description', 'Old Description')
|
|
->assertSet('form.amount', '50.000');
|
|
});
|
|
|
|
it('can update an expense', function () {
|
|
$expense = ExpenseModel::factory()->operational()->create([
|
|
'outlet_id' => $this->outlet->id,
|
|
'user_id' => $this->user->id,
|
|
]);
|
|
|
|
Livewire::actingAs($this->user)
|
|
->test(Expense::class)
|
|
->call('openModal', 'update', 'Ubah Pengeluaran', $expense->hash_id)
|
|
->set('form.expense', $expense)
|
|
->set('form.description', 'Updated Description')
|
|
->set('form.amount', '75000')
|
|
->call('update')
|
|
->assertHasNoErrors()
|
|
->assertDispatched('refreshDatatable');
|
|
|
|
$this->assertDatabaseHas('expenses', [
|
|
'id' => $expense->id,
|
|
'description' => 'Updated Description',
|
|
'amount' => 75000,
|
|
]);
|
|
});
|
|
|
|
it('can delete an expense', function () {
|
|
$expense = ExpenseModel::factory()->operational()->create([
|
|
'outlet_id' => $this->outlet->id,
|
|
'user_id' => $this->user->id,
|
|
]);
|
|
|
|
Livewire::actingAs($this->user)
|
|
->test(Expense::class)
|
|
->call('delete', $expense->id)
|
|
->assertHasNoErrors()
|
|
->assertDispatched('refreshDatatable');
|
|
|
|
$this->assertSoftDeleted('expenses', ['id' => $expense->id]);
|
|
});
|
|
|
|
it('cannot access expense page without permission', function () {
|
|
$this->user->roles()->detach();
|
|
$this->user->permissions()->detach();
|
|
|
|
$this->actingAs($this->user)
|
|
->get(route('studio.finance.expense.index'))
|
|
->assertForbidden();
|
|
});
|