Files
radicall/tests/Feature/Http/Client/WalletControllerTest.php

144 lines
6.0 KiB
PHP

<?php
namespace Tests\Feature\Http\Client;
use App\Enums\PaymentPurposeEnum;
use App\Enums\WithdrawRequestStatusEnum;
use App\Models\BankCard;
use App\Models\User;
use App\Models\Wallet;
use App\Models\WalletTransaction;
use App\Models\WithdrawRequest;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Inertia\Testing\AssertableInertia as Assert;
use Tests\TestCase;
class WalletControllerTest extends TestCase
{
use RefreshDatabase;
public function test_routes_require_authentication(): void
{
$this->get(route('dashboard.wallet.index'))->assertRedirect(route('login'));
$this->post(route('dashboard.wallet.deposit'))->assertRedirect(route('login'));
$this->post(route('dashboard.wallet.withdrawRequests.store'))->assertRedirect(route('login'));
$this->post(route('dashboard.wallet.bankCards.store'))->assertRedirect(route('login'));
}
public function test_index_renders_own_transactions_withdraw_requests_and_bank_cards(): void
{
$wallet = Wallet::factory()->create(['balance' => 5000]);
WalletTransaction::factory()->count(2)->create(['wallet_id' => $wallet->id]);
WalletTransaction::factory()->create();
$bankCard = BankCard::factory()->create(['user_id' => $wallet->user_id]);
WithdrawRequest::factory()->create(['user_id' => $wallet->user_id, 'bank_card_id' => $bankCard->id]);
WithdrawRequest::factory()->create();
$this->actingAs($wallet->user)->get(route('dashboard.wallet.index'))
->assertOk()
->assertInertia(fn (Assert $page) => $page
->component('Dashboard/Wallet/Index')
->has('transactions.data', 2)
->has('withdrawRequests', 1)
->has('bankCards', 1));
}
public function test_index_creates_wallet_for_user_without_one(): void
{
$user = User::factory()->create();
$this->actingAs($user)->get(route('dashboard.wallet.index'))->assertOk();
$this->assertDatabaseHas('wallets', ['user_id' => $user->id, 'balance' => 0]);
}
public function test_deposit_creates_top_up_payment_and_returns_gateway_url(): void
{
Http::fake(['gateway.zibal.ir/v1/request' => Http::response(['result' => 100, 'trackId' => 900])]);
$user = User::factory()->create();
$this->actingAs($user)->postJson(route('dashboard.wallet.deposit'), ['amount' => 100000])
->assertOk()
->assertJsonPath('url', 'https://gateway.zibal.ir/start/900');
$this->assertDatabaseHas('payments', ['track_id' => '900', 'amount' => 100000, 'payer_id' => $user->id, 'purpose' => PaymentPurposeEnum::WalletTopUp->value, 'invoice_id' => null]);
}
public function test_deposit_validates_amount(): void
{
$this->actingAs(User::factory()->create())->postJson(route('dashboard.wallet.deposit'), ['amount' => 100])->assertUnprocessable()->assertJsonValidationErrors('amount');
}
public function test_store_withdraw_request_creates_pending_request(): void
{
$wallet = Wallet::factory()->create(['balance' => 500000]);
$bankCard = BankCard::factory()->create(['user_id' => $wallet->user_id]);
$this->actingAs($wallet->user)
->post(route('dashboard.wallet.withdrawRequests.store'), ['amount' => 200000, 'bank_card_id' => $bankCard->id])
->assertRedirect(route('dashboard.wallet.index'))
->assertSessionHas('success');
$this->assertDatabaseHas('withdraw_requests', ['user_id' => $wallet->user_id, 'amount' => 200000, 'status' => WithdrawRequestStatusEnum::Pending->value]);
}
public function test_store_withdraw_request_rejects_insufficient_balance(): void
{
$wallet = Wallet::factory()->create(['balance' => 100000]);
$bankCard = BankCard::factory()->create(['user_id' => $wallet->user_id]);
$this->actingAs($wallet->user)
->post(route('dashboard.wallet.withdrawRequests.store'), ['amount' => 200000, 'bank_card_id' => $bankCard->id])
->assertSessionHasErrors('amount');
$this->assertDatabaseCount('withdraw_requests', 0);
}
public function test_store_withdraw_request_rejects_another_users_bank_card(): void
{
$wallet = Wallet::factory()->create(['balance' => 500000]);
$bankCard = BankCard::factory()->create();
$this->actingAs($wallet->user)
->post(route('dashboard.wallet.withdrawRequests.store'), ['amount' => 100000, 'bank_card_id' => $bankCard->id])
->assertSessionHasErrors('bank_card_id');
}
public function test_store_bank_card_creates_card_for_user(): void
{
$user = User::factory()->create();
$this->actingAs($user)
->post(route('dashboard.wallet.bankCards.store'), ['card_number' => '6037991234567890', 'holder_name' => 'علی'])
->assertRedirect(route('dashboard.wallet.index'));
$this->assertDatabaseHas('bank_cards', ['user_id' => $user->id, 'card_number' => '6037991234567890', 'holder_name' => 'علی']);
}
public function test_store_bank_card_validates_input(): void
{
$this->actingAs(User::factory()->create())
->post(route('dashboard.wallet.bankCards.store'), ['card_number' => '123'])
->assertSessionHasErrors(['card_number', 'holder_name']);
}
public function test_destroy_bank_card_deletes_own_card(): void
{
$bankCard = BankCard::factory()->create();
$this->actingAs($bankCard->user)->delete(route('dashboard.wallet.bankCards.destroy', $bankCard))->assertRedirect(route('dashboard.wallet.index'));
$this->assertDatabaseMissing('bank_cards', ['id' => $bankCard->id]);
}
public function test_destroy_bank_card_forbids_another_users_card(): void
{
$bankCard = BankCard::factory()->create();
$this->actingAs(User::factory()->create())->delete(route('dashboard.wallet.bankCards.destroy', $bankCard))->assertForbidden();
$this->assertDatabaseHas('bank_cards', ['id' => $bankCard->id]);
}
}