Skip to content

Commit eddb972

Browse files
authored
feat: recurring incomes and expenses acl between panels (#32)
* recurring income acl added * recurring expense acl added
1 parent 10a3e33 commit eddb972

13 files changed

+423
-18
lines changed

app/Filament/Concerns/RecurringIncomeRecurringExpenseTrait.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use Filament\Forms\Form;
1313
use Filament\Tables\Actions\BulkActionGroup;
1414
use Filament\Tables\Actions\DeleteAction;
15-
use Filament\Tables\Actions\DeleteBulkAction;
1615
use Filament\Tables\Actions\EditAction;
1716
use Filament\Tables\Columns\TextColumn;
1817
use Filament\Tables\Filters\SelectFilter;
@@ -25,6 +24,8 @@
2524
*/
2625
trait RecurringIncomeRecurringExpenseTrait
2726
{
27+
use BulkDeleter, UserFilterable;
28+
2829
public static function form(Form $form): Form
2930
{
3031
return $form
@@ -82,6 +83,8 @@ public static function table(Table $table): Table
8283
{
8384
return $table
8485
->columns([
86+
self::getUserColumn(),
87+
8588
TextColumn::make('person.name')
8689
->searchable()
8790
->sortable(),
@@ -105,6 +108,8 @@ public static function table(Table $table): Table
105108
TextColumn::make('remaining_recurrences'),
106109
])
107110
->filters([
111+
self::getUserFilter(),
112+
108113
SelectFilter::make('frequency')
109114
->options(Frequency::class),
110115
])
@@ -115,7 +120,7 @@ public static function table(Table $table): Table
115120
])
116121
->bulkActions([
117122
BulkActionGroup::make([
118-
DeleteBulkAction::make(),
123+
self::deleteBulkAction(),
119124
]),
120125
]);
121126
}

app/Filament/Resources/RecurringExpenseResource/Pages/ListRecurringExpenses.php

+3-7
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33
namespace App\Filament\Resources\RecurringExpenseResource\Pages;
44

5+
use App\Filament\Concerns\UserFilterable;
56
use App\Filament\Resources\RecurringExpenseResource;
67
use Filament\Actions\CreateAction;
78
use Filament\Resources\Pages\ListRecords;
8-
use Illuminate\Database\Eloquent\Builder;
99

1010
class ListRecurringExpenses extends ListRecords
1111
{
12+
use UserFilterable;
13+
1214
protected static string $resource = RecurringExpenseResource::class;
1315

1416
protected function getHeaderActions(): array
@@ -17,10 +19,4 @@ protected function getHeaderActions(): array
1719
CreateAction::make(),
1820
];
1921
}
20-
21-
public function filterTableQuery(Builder $query): Builder
22-
{
23-
return parent::filterTableQuery($query)
24-
->where('user_id', auth()->id());
25-
}
2622
}

app/Filament/Resources/RecurringIncomeResource/Pages/ListRecurringIncomes.php

+3-7
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33
namespace App\Filament\Resources\RecurringIncomeResource\Pages;
44

5+
use App\Filament\Concerns\UserFilterable;
56
use App\Filament\Resources\RecurringIncomeResource;
67
use Filament\Actions\CreateAction;
78
use Filament\Resources\Pages\ListRecords;
8-
use Illuminate\Database\Eloquent\Builder;
99

1010
class ListRecurringIncomes extends ListRecords
1111
{
12+
use UserFilterable;
13+
1214
protected static string $resource = RecurringIncomeResource::class;
1315

1416
protected function getHeaderActions(): array
@@ -17,10 +19,4 @@ protected function getHeaderActions(): array
1719
CreateAction::make(),
1820
];
1921
}
20-
21-
public function filterTableQuery(Builder $query): Builder
22-
{
23-
return parent::filterTableQuery($query)
24-
->where('user_id', auth()->id());
25-
}
2622
}

app/Policies/RecurringExpensePolicy.php

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Policies;
44

5+
use App\Enums\PanelId;
56
use App\Models\RecurringExpense;
67
use App\Models\User;
78
use Illuminate\Auth\Access\HandlesAuthorization;
@@ -22,16 +23,24 @@ public function view(User $user, RecurringExpense $recurringExpense): bool
2223

2324
public function create(User $user): bool
2425
{
25-
return true;
26+
return PanelId::APP->isCurrentPanel();
2627
}
2728

2829
public function update(User $user, RecurringExpense $recurringExpense): bool
2930
{
31+
if (PanelId::FAMILY->isCurrentPanel()) {
32+
return false;
33+
}
34+
3035
return $recurringExpense->user_id === $user->id;
3136
}
3237

3338
public function delete(User $user, RecurringExpense $recurringExpense): bool
3439
{
40+
if (PanelId::FAMILY->isCurrentPanel()) {
41+
return false;
42+
}
43+
3544
return $recurringExpense->user_id === $user->id;
3645
}
3746
}

app/Policies/RecurringIncomePolicy.php

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Policies;
44

5+
use App\Enums\PanelId;
56
use App\Models\RecurringIncome;
67
use App\Models\User;
78
use Illuminate\Auth\Access\HandlesAuthorization;
@@ -22,16 +23,24 @@ public function view(User $user, RecurringIncome $recurringIncome): bool
2223

2324
public function create(User $user): bool
2425
{
25-
return true;
26+
return PanelId::APP->isCurrentPanel();
2627
}
2728

2829
public function update(User $user, RecurringIncome $recurringIncome): bool
2930
{
31+
if (PanelId::FAMILY->isCurrentPanel()) {
32+
return false;
33+
}
34+
3035
return $recurringIncome->user_id === $user->id;
3136
}
3237

3338
public function delete(User $user, RecurringIncome $recurringIncome): bool
3439
{
40+
if (PanelId::FAMILY->isCurrentPanel()) {
41+
return false;
42+
}
43+
3544
return $recurringIncome->user_id === $user->id;
3645
}
3746
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
use App\Enums\PanelId;
4+
use App\Filament\Resources\RecurringExpenseResource;
5+
use App\Filament\Resources\RecurringExpenseResource\Pages\ListRecurringExpenses;
6+
use App\Models\RecurringExpense;
7+
use App\Models\User;
8+
use Illuminate\Foundation\Testing\RefreshDatabase;
9+
10+
use function Pest\Livewire\livewire;
11+
12+
uses(RefreshDatabase::class);
13+
14+
beforeEach(function () {
15+
$this->user = User::factory()->create();
16+
$this->actingAs($this->user);
17+
18+
$this->recurringExpense = RecurringExpense::factory()->for($this->user)->create([
19+
'description' => 'User 1 RecurringExpense',
20+
]);
21+
22+
PanelId::FAMILY->setCurrentPanel();
23+
});
24+
25+
it('cannot display create action', function () {
26+
livewire(ListRecurringExpenses::class)
27+
->assertActionHidden('create');
28+
});
29+
30+
it('cannot display edit action', function () {
31+
livewire(ListRecurringExpenses::class)
32+
->assertTableActionHidden('edit', $this->recurringExpense->id);
33+
});
34+
35+
it('cannot display delete action', function () {
36+
livewire(ListRecurringExpenses::class)
37+
->assertTableActionHidden('delete', $this->recurringExpense->id);
38+
});
39+
40+
it('cannot display import action', function () {
41+
livewire(ListRecurringExpenses::class)
42+
->assertTableActionHidden('delete', $this->recurringExpense->id);
43+
});
44+
45+
it('cannot display bulk delete action', function () {
46+
livewire(ListRecurringExpenses::class)
47+
->set('selectedTableRecords', [$this->recurringExpense])
48+
->assertTableBulkActionHidden('delete');
49+
});
50+
51+
it('cannot render create recurringExpense page', function () {
52+
$this->get(RecurringExpenseResource::getUrl('create'))
53+
->assertForbidden();
54+
});
55+
56+
it('cannot perform recurringExpense update action', function () {
57+
livewire(RecurringExpenseResource\Pages\EditRecurringExpense::class, [
58+
'record' => $this->recurringExpense->getRouteKey(),
59+
])
60+
->assertForbidden();
61+
});
62+
63+
it('cannot perform delete recurringExpense action', function () {
64+
livewire(RecurringExpenseResource\Pages\EditRecurringExpense::class, [
65+
'record' => $this->recurringExpense->getRouteKey(),
66+
])
67+
->assertForbidden();
68+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
use App\Enums\PanelId;
4+
use App\Filament\Resources\RecurringExpenseResource\Pages\ListRecurringExpenses;
5+
use App\Models\RecurringExpense;
6+
use App\Models\User;
7+
use Illuminate\Foundation\Testing\RefreshDatabase;
8+
9+
use function Pest\Livewire\livewire;
10+
11+
uses(RefreshDatabase::class);
12+
13+
beforeEach(function () {
14+
$this->user = User::factory()->create();
15+
$this->actingAs($this->user);
16+
17+
$this->recurringExpense1 = RecurringExpense::factory()->for($this->user)->create([
18+
'description' => 'User 1 RecurringExpense',
19+
]);
20+
21+
$this->recurringExpense2 = RecurringExpense::factory()->for(User::factory())->create([
22+
'description' => 'User 2 RecurringExpense',
23+
]);
24+
25+
PanelId::FAMILY->setCurrentPanel();
26+
});
27+
28+
it('can display user filter', function () {
29+
livewire(ListRecurringExpenses::class)
30+
->assertTableFilterVisible('user');
31+
});
32+
33+
it('can display user columns', function () {
34+
livewire(ListRecurringExpenses::class)
35+
->assertTableColumnVisible('user.name');
36+
});
37+
38+
it('display user columns', function () {
39+
livewire(ListRecurringExpenses::class)
40+
->assertSee([$this->recurringExpense1->description])
41+
->assertSee([$this->recurringExpense2->description]);
42+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
use App\Enums\PanelId;
4+
use App\Filament\Resources\RecurringExpenseResource\Pages\ListRecurringExpenses;
5+
use App\Models\RecurringExpense;
6+
use App\Models\User;
7+
use Illuminate\Foundation\Testing\RefreshDatabase;
8+
9+
use function Pest\Livewire\livewire;
10+
11+
uses(RefreshDatabase::class);
12+
13+
beforeEach(function () {
14+
$this->user = User::factory()->create();
15+
$this->actingAs($this->user);
16+
17+
$this->recurringExpense = RecurringExpense::factory()->for($this->user)->create([
18+
'description' => 'User 1 RecurringExpense',
19+
]);
20+
21+
PanelId::APP->setCurrentPanel();
22+
});
23+
24+
it('can display create action', function () {
25+
livewire(ListRecurringExpenses::class)
26+
->assertActionVisible('create');
27+
});
28+
29+
it('can display edit action', function () {
30+
livewire(ListRecurringExpenses::class)
31+
->assertTableActionVisible('edit', $this->recurringExpense->id);
32+
});
33+
34+
it('can display delete action', function () {
35+
livewire(ListRecurringExpenses::class)
36+
->assertTableActionVisible('delete', $this->recurringExpense->id);
37+
});
38+
39+
it('can display bulk delete action', function () {
40+
livewire(ListRecurringExpenses::class)
41+
->set('selectedTableRecords', [$this->recurringExpense])
42+
->assertTableBulkActionVisible('delete');
43+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
use App\Enums\PanelId;
4+
use App\Filament\Resources\RecurringExpenseResource\Pages\ListRecurringExpenses;
5+
use App\Models\RecurringExpense;
6+
use App\Models\User;
7+
use Illuminate\Foundation\Testing\RefreshDatabase;
8+
9+
use function Pest\Livewire\livewire;
10+
11+
uses(RefreshDatabase::class);
12+
13+
beforeEach(function () {
14+
$this->user = User::factory()->create();
15+
$this->actingAs($this->user);
16+
17+
$this->recurringExpense1 = RecurringExpense::factory()->for($this->user)->create([
18+
'description' => 'User 1 RecurringExpense',
19+
]);
20+
21+
$this->recurringExpense2 = RecurringExpense::factory(User::factory())->create([
22+
'description' => 'User 2 RecurringExpense',
23+
]);
24+
25+
PanelId::APP->setCurrentPanel();
26+
});
27+
28+
it('cannot display user filter', function () {
29+
livewire(ListRecurringExpenses::class)
30+
->assertTableFilterHidden('user');
31+
});
32+
33+
it('cannot display user columns', function () {
34+
livewire(ListRecurringExpenses::class)
35+
->assertTableColumnHidden('user.name');
36+
});
37+
38+
it('can only list auth user recurringExpenses', function () {
39+
livewire(ListRecurringExpenses::class)
40+
->assertSee([$this->recurringExpense1->description])
41+
->assertDontSee([$this->recurringExpense2->description]);
42+
});

0 commit comments

Comments
 (0)