Skip to content

Commit

Permalink
Merge pull request #9 from phi-rakib/deposit-policy-validation-observ…
Browse files Browse the repository at this point in the history
…er-test

Deposit policy validation observer test
  • Loading branch information
phi-rakib authored Jun 1, 2024
2 parents bdd254c + ff3f7d7 commit 7ce4564
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 7 deletions.
18 changes: 15 additions & 3 deletions app/Http/Controllers/DepositController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,53 @@

namespace App\Http\Controllers;

use App\Http\Requests\StoreDepositRequest;
use App\Models\Deposit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;

class DepositController extends Controller
{
public function index()
{
Gate::authorize('viewAny', Deposit::class);

return Deposit::with(['account', 'depositCategory', 'paymentMethod'])
->latest()
->paginate(20);
}

public function store(Request $request)
public function store(StoreDepositRequest $request)
{
Gate::authorize('create', Deposit::class);

$deposit = Deposit::create($request->validated());

return response()->json(['message' => "$deposit->amount Deposited in account $deposit->account->name"], 201);
}

public function update(Deposit $deposit, Request $request)
{
$deposit->update($request->validated());
Gate::authorize('update', $deposit);

$deposit->update($request->all());

return response()->json(['message' => 'Deposit updated']);
}

public function destroy(Deposit $deposit)
{
Gate::authorize('delete', $deposit);

$deposit->delete();

return response()->json(['message' => 'Deposited amount deleted']);
return response()->json(['message' => 'Deposited amount deleted'], 204);
}

public function show(Deposit $deposit)
{
Gate::authorize('view', $deposit);

$deposit->load([
'account',
'depositCategory',
Expand Down
34 changes: 34 additions & 0 deletions app/Http/Requests/StoreDepositRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;

class StoreDepositRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return Auth::check();
}

/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'account_id' => 'required|integer|exists:accounts,id',
'deposit_category_id' => 'required|integer|exists:deposit_categories,id',
'payment_method_id' => 'required|integer|exists:payment_methods,id',
'amount' => 'required|numeric',
'deposit_date' => 'required|date',
'notes' => 'nullable',
];
}
}
3 changes: 2 additions & 1 deletion app/Models/Deposit.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Deposit extends Model
{
use HasFactory;
use HasFactory, SoftDeletes;

protected $fillable = [
'account_id',
Expand Down
23 changes: 23 additions & 0 deletions app/Observers/DepositObserver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Observers;

use App\Models\Deposit;

class DepositObserver
{
public function creating(Deposit $deposit)
{
$deposit->created_by = auth()->id();
}

public function updating(Deposit $deposit)
{
$deposit->updated_by = auth()->id();
}

public function deleting(Deposit $deposit)
{
$deposit->deleted_by = auth()->id();
}
}
65 changes: 65 additions & 0 deletions app/Policies/DepositPolicy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace App\Policies;

use App\Models\Deposit;
use App\Models\User;

class DepositPolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return $user->can('deposit-list');
}

/**
* Determine whether the user can view the model.
*/
public function view(User $user, Deposit $deposit): bool
{
return $user->can('deposit-list');
}

/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return $user->can('deposit-create');
}

/**
* Determine whether the user can update the model.
*/
public function update(User $user, Deposit $deposit): bool
{
return $user->can('deposit-edit');
}

/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, Deposit $deposit): bool
{
return $user->can('deposit-delete');
}

/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, Deposit $deposit): bool
{
return $user->can('deposit-restore');
}

/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, Deposit $deposit): bool
{
return $user->can('deposit-force-delete');
}
}
3 changes: 3 additions & 0 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
namespace App\Providers;

use App\Models\Account;
use App\Models\Deposit;
use App\Models\DepositCategory;
use App\Observers\AccountObserver;
use App\Observers\DepositCategoryObserver;
use App\Observers\DepositObserver;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
Expand All @@ -25,5 +27,6 @@ public function boot(): void
{
Account::observe(AccountObserver::class);
DepositCategory::observe(DepositCategoryObserver::class);
Deposit::observe(DepositObserver::class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ public function up(): void
$table->decimal('amount', 8, 2);
$table->date('deposit_date');
$table->string('notes');
$table->unsignedBigInteger('created_by');
$table->unsignedBigInteger('updated_by')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
$table->timestamps();
$table->softDeletes();
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$table->foreign('deposit_category_id')->references('id')->on('deposit_categories')->onDelete('cascade');
$table->foreign('payment_method_id')->references('id')->on('payment_methods')->onDelete('cascade');
$table->foreign('created_by')->references('id')->on('users')->onDelete('cascade');
$table->foreign('updated_by')->references('id')->on('users')->onDelete('cascade');
$table->foreign('deleted_by')->references('id')->on('users')->onDelete('cascade');
});
}

Expand Down
6 changes: 6 additions & 0 deletions database/seeders/PermissionSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ public function run(): void
'payment-method-delete',
'payment-method-restore',
'payment-method-force-delete',
'deposit-list',
'deposit-create',
'deposit-edit',
'deposit-delete',
'deposit-restore',
'deposit-force-delete',
];

foreach ($permissions as $permission) {
Expand Down
6 changes: 3 additions & 3 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Route::post('login', [AuthController::class, 'login']);

Route::middleware(['auth:sanctum'])->group(function () {
Route::resource('accounts', AccountController::class);
Route::resource('depositCategories', DepositCategoryController::class);
Route::resource('deposits', DepositController::class);
Route::apiResource('accounts', AccountController::class);
Route::apiResource('depositCategories', DepositCategoryController::class);
Route::apiResource('deposits', DepositController::class);
});
109 changes: 109 additions & 0 deletions tests/Feature/DepositTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

namespace Tests\Feature;

use App\Models\Deposit;
use App\Models\User;
use Database\Seeders\PermissionSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class DepositTest extends TestCase
{
use RefreshDatabase;

private $user;

public function setUp(): void
{
parent::setUp();

$this->user = User::factory()->create();

Sanctum::actingAs($this->user);

$this->artisan('db:seed', ['--class' => PermissionSeeder::class]);
$this->app->make(\Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions();
}

public function test_user_can_deposit()
{
$this->user->givePermissionTo('deposit-create');

$deposit = Deposit::factory()->make();

$response = $this->post(route('deposits.store'), $deposit->toArray());

$response->assertStatus(201);

$response->assertJson([
'message' => "$deposit->amount Deposited in account $deposit->account->name",
]);

$this->assertDatabaseHas('deposits', [
'account_id' => $deposit->account_id,
'amount' => $deposit->amount,
'deposit_date' => $deposit->deposit_date,
]);
}

public function test_user_can_update_deposit()
{
$this->user->givePermissionTo('deposit-edit');

$deposit = Deposit::factory()->create();

$response = $this->put(route('deposits.update', $deposit), [
'amount' => 5000,
]);

$response->assertStatus(200);

$this->assertDatabaseHas('deposits', [
'id' => $deposit->id,
'amount' => 5000,
]);
}

public function test_user_can_delete_deposit()
{
$this->user->givePermissionTo('deposit-delete');

$deposit = Deposit::factory()->create();

$response = $this->delete(route('deposits.destroy', $deposit));

$response->assertStatus(204);

$this->assertSoftDeleted('deposits', [
'id' => $deposit->id,
]);
}

public function test_user_can_view_all_deposits()
{
$this->user->givePermissionTo('deposit-list');

Deposit::factory(10)->create();

$response = $this->get(route('deposits.index'));

$response->assertStatus(200);

$response->assertJsonCount(10, 'data');
}

public function test_user_can_view_deposit()
{
$this->user->givePermissionTo('deposit-list');

$deposit = Deposit::factory()->create();

$response = $this->get(route('deposits.show', $deposit->id));

$response->assertStatus(200);

$response->assertJson($deposit->toArray());
}
}

0 comments on commit 7ce4564

Please sign in to comment.