144 lines
6.0 KiB
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]);
|
|
}
|
|
}
|