ifnex/04_Laravel/tests/Feature/Api/PaymentControllerTest.php
Kazem Alghasi e1c4385a9c feat(finance): implement Filament admin panel and expand wallet/discount features
Implement a comprehensive financial management suite within the Filament
admin panel, including new resources for payments and discount codes,
along with a financial dashboard.

- feat(ui): add Filament Dashboard with finance overview and transaction
  widgets
- feat(ui): implement PaymentResource for monitoring gateway transactions
- feat(ui): complete DiscountCodeResource with full CRUD and filtering
- feat(wallet): add automatic wallet creation on balance retrieval
- fix(wallet): resolve null handling in isFrozen() and balance viewing
- fix(db): correct enum type from 'percent' to 'percentage' in
  discount_codes migration
- fix(api): update pricing calculation endpoint to /api/v1/calculate
- test: add 21 new feature and service tests covering wallet, payment,
  and discount logic
- chore: remove obsolete PaymentGatewayService and update project status
2026-08-08 03:15:51 +03:30

124 lines
3.5 KiB
PHP

<?php
namespace Tests\Feature\Api;
use App\Enums\TransactionStatus;
use App\Models\User;
use App\Models\Wallet;
use App\Models\WalletTransaction;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class PaymentControllerTest extends TestCase
{
use RefreshDatabase;
private User $user;
private Wallet $wallet;
protected function setUp(): void
{
parent::setUp();
$this->user = User::factory()->create();
$this->wallet = Wallet::create([
'user_id' => $this->user->id,
'balance' => 0,
]);
Sanctum::actingAs($this->user);
}
#[Test]
public function it_redirects_to_gateway_for_payment()
{
$response = $this->postJson('/api/v1/payment/redirect', [
'amount' => 100000,
'description' => 'شارژ تستی',
]);
$response->assertStatus(200)
->assertJson([
'success' => true,
'is_mock' => true,
])
->assertJsonStructure([
'success',
'message',
'payment_url',
'transaction_id',
'authority',
'amount',
'is_mock',
]);
}
#[Test]
public function it_validates_minimum_deposit_amount()
{
$response = $this->postJson('/api/v1/payment/redirect', [
'amount' => 1000,
'description' => 'شارژ تستی',
]);
$response->assertStatus(422)
->assertJsonValidationErrors(['amount']);
}
#[Test]
public function it_prevents_payment_for_frozen_wallet()
{
$this->wallet->update(['is_frozen' => true]);
$response = $this->postJson('/api/v1/payment/redirect', [
'amount' => 100000,
'description' => 'شارژ تستی',
]);
$response->assertStatus(403)
->assertJson(['message' => 'کیف پول شما مسدود است.']);
}
#[Test]
public function it_completes_mock_payment_successfully()
{
$response = $this->postJson('/api/v1/payment/redirect', [
'amount' => 100000,
'description' => 'شارژ تستی',
]);
$response->assertStatus(200);
$transactionId = $response->json('transaction_id');
$authority = $response->json('authority');
$transaction = WalletTransaction::findOrFail($transactionId);
$this->assertEquals(TransactionStatus::PENDING, $transaction->status);
$callbackResponse = $this->get("/api/v1/payment/callback?Authority={$authority}&Status=OK");
$callbackResponse->assertRedirect();
$transaction->refresh();
$this->assertEquals(TransactionStatus::COMPLETED, $transaction->status);
$this->wallet->refresh();
$this->assertEquals(100000, $this->wallet->balance);
}
#[Test]
public function it_checks_transaction_status()
{
$response = $this->postJson('/api/v1/payment/redirect', [
'amount' => 100000,
'description' => 'شارژ تستی',
]);
$transactionId = $response->json('transaction_id');
$checkResponse = $this->get("/api/v1/payment/check/{$transactionId}");
$checkResponse->assertStatus(200)
->assertJson([
'transaction_id' => $transactionId,
'status_code' => TransactionStatus::PENDING->value,
]);
}
}