Skip to content

Commit bf10e0c

Browse files
committed
feat(test): (LAR-86) add test
1 parent 374f8fa commit bf10e0c

File tree

7 files changed

+152
-53
lines changed

7 files changed

+152
-53
lines changed

app/Filament/Resources/UserResource.php

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55
namespace App\Filament\Resources;
66

7+
use Carbon\Carbon;
78
use App\Models\User;
89
use Filament\Tables;
910
use Filament\Tables\Table;
11+
use App\Events\UserBannedEvent;
1012
use Filament\Resources\Resource;
11-
use Filament\Tables\Actions\Action;
13+
use App\Events\UserUnbannedEvent;
1214
use Filament\Forms\Components\TextInput;
13-
use Filament\Tables\Actions\ActionGroup;
15+
use Filament\Notifications\Notification;
1416
use Illuminate\Database\Eloquent\Builder;
1517
use App\Filament\Resources\UserResource\Pages;
1618
use Awcodes\FilamentBadgeableColumn\Components\Badge;
@@ -67,36 +69,45 @@ public static function table(Table $table): Table
6769
->nullable(),
6870
])
6971
->actions([
70-
ActionGroup::make([
71-
Action::make('ban')
72+
Tables\Actions\Action::make('ban')
7273
->label(__('actions.ban'))
7374
->icon('untitledui-archive')
7475
->color('warning')
7576
->visible(fn ($record) => $record->banned_at == null)
7677
->modalHeading(__('Bannir l\'utilisateur'))
7778
->modalDescription(__('Veuillez entrer la raison du bannissement.'))
7879
->form([
79-
TextInput::make('banned_reason')
80+
81+
TextInput::make('banned_reason')
8082
->label(__('Raison du bannissement'))
8183
->required(),
8284
])
83-
->action(function ($record, array $data) {
84-
$record->ban($data['banned_reason']);
85+
->action(function (User $record, array $data) {
86+
if (!self::canBanUser($record)) {
87+
Notification::make()
88+
->warning()
89+
->title(__('Impossible de bannir'))
90+
->body(__('Vous ne pouvez pas bannir un administrateur.'))
91+
->duration(5000)
92+
->send();
93+
94+
return;
95+
}
96+
self::BanUserAction($record, $data['banned_reason']);
8597
})
8698
->requiresConfirmation(),
8799

88-
Action::make('unban')
100+
Tables\Actions\Action::make('unban')
89101
->label(__('actions.unban'))
90102
->icon('heroicon-o-check-circle')
91103
->color('success')
92104
->visible(fn ($record) => $record->banned_at !== null)
93-
->action(function ($record) {
94-
$record->unban();
105+
->action(function (User $record) {
106+
self::UnbanUserAction($record);
95107
})
96108
->requiresConfirmation(),
97109

98110
Tables\Actions\DeleteAction::make(),
99-
])->icon('heroicon-m-ellipsis-horizontal'),
100111
])
101112
->bulkActions([
102113
Tables\Actions\DeleteBulkAction::make(),
@@ -109,4 +120,41 @@ public static function getPages(): array
109120
'index' => Pages\ListUsers::route('/'),
110121
];
111122
}
123+
124+
public static function BanUserAction(User $record, $reason): void
125+
{
126+
$record->banned_at = Carbon::now();
127+
$record->banned_reason = $reason;
128+
$record->save();
129+
130+
Notification::make()
131+
->success()
132+
->duration(5000)
133+
->title(__('L\'utilisateur à été banni'))
134+
->body(__('L\'utilisateur à été notifier qu\'il à été banni'))
135+
->send();
136+
137+
event(new UserBannedEvent($record));
138+
}
139+
140+
public static function UnbanUserAction(User $record): void
141+
{
142+
$record->banned_at = null;
143+
$record->banned_reason = null;
144+
$record->save();
145+
146+
Notification::make()
147+
->success()
148+
->title(__('L\'utilisateur à été dé-banni'))
149+
->duration(5000)
150+
->body(__('L\'utilisateur à été notifier qu\'il peut de nouveau se connecter'))
151+
->send();
152+
153+
event(new UserUnbannedEvent($record));
154+
}
155+
156+
public static function canBanUser(User $record): bool
157+
{
158+
return !$record->hasRole('admin');
159+
}
112160
}

app/Filament/Resources/UserResource/Pages/ListUsers.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,26 @@
44

55
namespace App\Filament\Resources\UserResource\Pages;
66

7+
use Filament\Resources\Components\Tab;
78
use App\Filament\Resources\UserResource;
89
use Filament\Resources\Pages\ListRecords;
910

1011
final class ListUsers extends ListRecords
1112
{
1213
protected static string $resource = UserResource::class;
13-
}
14+
15+
public function getTabs() : array
16+
{
17+
return [
18+
__('Tout') => Tab::make('Tout'),
19+
__("Bannis") => Tab::make(__('Bannis'))
20+
->modifyQueryUsing(function ($query) {
21+
return $query->isBanned();
22+
}),
23+
__("Non Bannis") => Tab::make(__('Non Bannis'))
24+
->modifyQueryUsing(function ($query) {
25+
return $query->isNotBanned();
26+
}),
27+
];
28+
}
29+
}

app/Models/User.php

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -475,23 +475,25 @@ public function scopeTopContributors(Builder $query): Builder
475475
return $query->withCount(['discussions'])->orderByDesc('discussions_count');
476476
}
477477

478-
public function ban($reason = null)
478+
/**
479+
* Get the banned user.
480+
*
481+
* @param Builder<User> $query
482+
* @return Builder<User>
483+
*/
484+
public function scopeIsBanned(Builder $query): Builder
479485
{
480-
$this->update([
481-
'banned_at' => now(),
482-
'banned_reason' => $reason,
483-
]);
484-
485-
event(new UserBannedEvent($this));
486+
return $query->whereNotNull('banned_at');
486487
}
487488

488-
public function unban()
489+
/**
490+
* Get the unbanned user.
491+
*
492+
* @param Builder<User> $query
493+
* @return Builder<User>
494+
*/
495+
public function scopeIsNotBanned(Builder $query): Builder
489496
{
490-
$this->update([
491-
'banned_at' => null,
492-
'banned_reason' => null,
493-
]);
494-
495-
event(new UserUnbannedEvent($this));
497+
return $query->whereNull('banned_at');
496498
}
497499
}

composer.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lang/fr/actions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
'cancel' => 'Annuler',
1212
'save' => 'Enregistrer',
1313
'ban' => 'Bannir',
14-
'unban' => 'Annuler le bannissement',
14+
'unban' => 'Dé-bannir',
1515

1616
];

routes/cpanel.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
use App\Http\Controllers\Cpanel;
66
use Illuminate\Support\Facades\Route;
77

8-
Route::redirect('/', 'cpanel/home');
9-
Route::get('/home', Cpanel\DashboardController::class)->name('home');
10-
Route::get('/analytics', Cpanel\AnalyticsController::class)->name('analytics');
11-
Route::prefix('users')->as('users.')->group(function (): void {
12-
Route::get('/', Cpanel\UserController::class)->name('browse');
13-
});
8+
Route::group(['middleware' => ['role:admin']], function () {
9+
Route::redirect('/', 'cpanel/home');
10+
Route::get('/home', Cpanel\DashboardController::class)->name('home');
11+
Route::get('/analytics', Cpanel\AnalyticsController::class)->name('analytics');
12+
Route::prefix('users')->as('users.')->group(function (): void {
13+
Route::get('/', Cpanel\UserController::class)->name('browse');
14+
});
15+
});

tests/Feature/UserResourceTest.php

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,74 @@
22

33
declare(strict_types=1);
44

5+
use Carbon\Carbon;
56
use App\Models\User;
6-
use Livewire\Livewire;
7-
use App\Filament\Resources\UserResource;
8-
use App\Filament\Resources\UserResource\Pages\ListUsers;
7+
use App\Events\UserBannedEvent;
8+
use App\Events\UserUnbannedEvent;
9+
use Spatie\Permission\Models\Role;
910
use Illuminate\Support\Facades\Event;
11+
use Illuminate\Support\Facades\Queue;
12+
use App\Filament\Resources\UserResource;
1013
use Illuminate\Support\Facades\Notification;
14+
use App\Filament\Resources\UserResource\Pages\ListUsers;
1115

1216

1317
beforeEach(function (): void {
1418
Event::fake();
19+
Notification::fake();
20+
Queue::fake();
1521
$this->user = $this->login();
1622
});
1723

1824
describe(UserResource::class, function() {
19-
it('can ban a user through Filament and send a ban notification', function () {
25+
it('only admin can ban a user and send a ban notification', function () {
26+
27+
Role::create(['name' => 'user']);
28+
$admin = $this->user->assignRole('user');
2029

30+
$user = User::factory()->create();
31+
32+
// $this->actingAs($admin);
33+
34+
UserResource::BanUserAction($user, 'Violation des règles de la communauté');
35+
36+
$user->refresh();
37+
38+
expect($user->banned_at)->toBeInstanceOf(Carbon::class)
39+
->and($user->banned_reason)->toBe('Violation des règles de la communauté');
40+
41+
Event::assertDispatched(UserBannedEvent::class);
42+
});
43+
44+
it('can unban a user and send a unban notification', function () {
45+
Role::create(['name' => 'admin']);
2146
$admin = $this->user->assignRole('admin');
2247

2348
$user = User::factory()->create([
24-
'banned_at' => null,
25-
'banned_reason' => null,
49+
'banned_at' => now(),
50+
'banned_reason' => 'Violation des règles de la communauté'
2651
]);
2752

2853
$this->actingAs($admin);
29-
30-
Livewire::test(ListUsers::class, ['record' => $user->id])
31-
->call('banUser', 'Violation des règles de la communauté')
32-
->assertHasNoErrors();
54+
55+
UserResource::UnbanUserAction($user);
3356

3457
$user->refresh();
3558

36-
expect($user->banned_at)->not->toBeNull();
37-
expect($user->banned_reason)->toBe('Violation des règles de la communauté');
59+
expect($user->banned_at)->toBeNull()
60+
->and($user->banned_reason)->toBeNull();
3861

39-
Notification::assertSentTo(
40-
[$user], UserBannedNotification::class
41-
);
62+
Event::assertDispatched(UserUnbannedEvent::class);
4263
});
64+
65+
it('prevents a banned user from logging in', function () {
66+
$user = User::factory()->create([
67+
'banned_at' => now(),
68+
]);
4369

70+
$this->actingAs($user)
71+
->get('/dashboard')
72+
->assertRedirect(route('login'))
73+
->assertSessionHasErrors(['email']);
74+
});
4475
});

0 commit comments

Comments
 (0)