From 246ca52d31a91e0eeff76bbc43f60c23046feb72 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 04:25:42 +0000 Subject: [PATCH] Add feature tests for payment routes - Create `tests/Feature/PaymentRouteTest.php` with comprehensive test cases. - Mock `ModuleHandlerInterface` and `PaymentGatewayInterface` for isolation. - Handle environment setup including database seeding, mix manifest creation, and middleware bypass. - Verify behavior of checkout, purchase, return, cancel, embed, and status routes. Co-authored-by: juzaweb <47020363+juzaweb@users.noreply.github.com> --- tests/Feature/PaymentRouteTest.php | 260 +++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 tests/Feature/PaymentRouteTest.php diff --git a/tests/Feature/PaymentRouteTest.php b/tests/Feature/PaymentRouteTest.php new file mode 100644 index 0000000..2fd9b40 --- /dev/null +++ b/tests/Feature/PaymentRouteTest.php @@ -0,0 +1,260 @@ +user = User::factory()->create(); + $this->actingAs($this->user); + + // Define currentActor macro if not exists + if (!Request::hasMacro('currentActor')) { + Request::macro('currentActor', function () { + return $this->user(); + }); + } + + if (!\Illuminate\Support\Facades\Schema::hasColumn('languages', 'default')) { + \Illuminate\Support\Facades\Schema::table('languages', function ($table) { + $table->boolean('default')->default(false); + }); + } + + // Seed default language + $language = \Juzaweb\Modules\Core\Translations\Models\Language::firstOrCreate( + ['code' => 'en'], + ['name' => 'English'] + ); + + $language->default = true; + $language->save(); + + app()->setLocale('en'); + + $this->withoutMiddleware([ + \Juzaweb\Modules\Core\Http\Middleware\MultipleLanguage::class, + ]); + + // Register Test Module + $this->moduleHandler = Mockery::mock(ModuleHandlerInterface::class); + $this->moduleHandler->shouldReceive('getReturnUrl')->andReturn('http://example.com/return'); + $this->moduleHandler->shouldReceive('createOrder')->andReturnUsing(function($params) { + return $this->order; + }); + $this->moduleHandler->shouldReceive('success'); + $this->moduleHandler->shouldReceive('fail'); + $this->moduleHandler->shouldReceive('cancel'); + + PaymentManager::registerModule('test_module', $this->moduleHandler); + + // Register Test Driver + $this->gateway = Mockery::mock(PaymentGatewayInterface::class); + $this->gateway->shouldReceive('isReturnInEmbed')->andReturn(false); + + $driverAdapter = Mockery::mock(PaymentDriverAdapter::class); + $driverAdapter->shouldReceive('makeDriver')->andReturn($this->gateway); + $driverAdapter->shouldReceive('getConfig')->andReturn([]); + $driverAdapter->shouldReceive('hasSandbox')->andReturn(true); + $driverAdapter->shouldReceive('isReturnInEmbed')->andReturn(false); + $driverAdapter->shouldReceive('getDriver')->andReturn('TestDriver'); + + PaymentManager::registerDriver('TestDriver', fn() => $driverAdapter); + + // Create Payment Method + $this->paymentMethod = PaymentMethod::create([ + 'name' => 'Test Method', + 'driver' => 'TestDriver', + 'active' => true, + 'config' => [], + ]); + + // Create Order + $this->order = Order::create([ + 'code' => 'ORD-' . Str::random(10), + 'quantity' => 1, + 'total_price' => 100, + 'total' => 100, + 'payment_method_id' => $this->paymentMethod->id, + 'payment_method_name' => 'Test Method', + 'module' => 'test_module', + 'payment_status' => OrderPaymentStatus::PENDING, + ]); + + $this->order->created_by = $this->user->id; + $this->order->save(); + } + + public function test_checkout_route() + { + $response = $this->postJson(route('payment.checkout', ['module' => 'test_module']), [ + 'method' => 'TestDriver', + ]); + + $response->assertStatus(200); + $response->assertJsonStructure(['order_id', 'order_code', 'amount', 'currency']); + } + + public function test_order_checkout_route() + { + $response = $this->get(route('payment.order.checkout', ['orderId' => $this->order->id])); + + $response->assertStatus(200); + $response->assertViewIs('payment::checkout.order'); + } + + public function test_purchase_route() + { + // Mock PurchaseResult + $purchaseResult = new PurchaseResult('TRANS-123', 'http://redirect.url'); + $purchaseResult->setSuccessful(false); + + $this->gateway->shouldReceive('purchase')->andReturn($purchaseResult); + + $response = $this->postJson(route('payment.purchase', ['module' => 'test_module']), [ + 'method' => 'TestDriver', + 'order_id' => $this->order->id, + ]); + + $response->assertStatus(200); + $response->assertJson([ + 'type' => 'redirect', + 'redirect' => 'http://redirect.url', + ]); + } + + public function test_return_route() + { + // Create PaymentHistory + $paymentHistory = PaymentHistory::create([ + 'method_id' => $this->paymentMethod->id, + 'payment_method' => $this->paymentMethod->driver, + 'module' => 'test_module', + 'status' => PaymentHistoryStatus::PROCESSING, + 'paymentable_type' => Order::class, + 'paymentable_id' => $this->order->id, + 'payment_id' => 'TRANS-123', + 'payer_type' => get_class($this->user), + 'payer_id' => $this->user->id, + ]); + + $completeResult = new CompleteResult('TRANS-123', true); + $completeResult->setSuccessful(true); + + $this->gateway->shouldReceive('complete')->andReturn($completeResult); + + $response = $this->getJson(route('payment.return', [ + 'module' => 'test_module', + 'paymentHistoryId' => $paymentHistory->id + ])); + + $response->assertStatus(200); + } + + public function test_cancel_route() + { + $paymentHistory = PaymentHistory::create([ + 'method_id' => $this->paymentMethod->id, + 'payment_method' => $this->paymentMethod->driver, + 'module' => 'test_module', + 'status' => PaymentHistoryStatus::PROCESSING, + 'paymentable_type' => Order::class, + 'paymentable_id' => $this->order->id, + 'payment_id' => 'TRANS-123', + 'payer_type' => get_class($this->user), + 'payer_id' => $this->user->id, + ]); + + $response = $this->getJson(route('payment.cancel', [ + 'module' => 'test_module', + 'paymentHistoryId' => $paymentHistory->id + ])); + + // Cancel route returns 422 warning response + $response->assertStatus(422); + $response->assertJson([ + 'success' => false, + 'message' => 'Payment has been cancelled!', + 'redirect' => 'http://example.com/return', + ]); + } + + public function test_embed_route() + { + $paymentHistory = PaymentHistory::create([ + 'method_id' => $this->paymentMethod->id, + 'payment_method' => $this->paymentMethod->driver, + 'module' => 'test_module', + 'status' => PaymentHistoryStatus::PROCESSING, + 'paymentable_type' => Order::class, + 'paymentable_id' => $this->order->id, + 'payer_type' => get_class($this->user), + 'payer_id' => $this->user->id, + ]); + + $response = $this->get(route('payment.embed', [ + 'module' => 'test_module', + 'paymentHistoryId' => $paymentHistory->id + ])); + + $response->assertStatus(200); + $response->assertViewIs('payment::method.embed'); + } + + public function test_status_route() + { + $paymentHistory = PaymentHistory::create([ + 'method_id' => $this->paymentMethod->id, + 'payment_method' => $this->paymentMethod->driver, + 'module' => 'test_module', + 'status' => PaymentHistoryStatus::SUCCESS, + 'paymentable_type' => Order::class, + 'paymentable_id' => $this->order->id, + 'payer_type' => get_class($this->user), + 'payer_id' => $this->user->id, + ]); + + $response = $this->getJson(route('payment.status', [ + 'module' => 'test_module', + 'paymentHistoryId' => $paymentHistory->id + ])); + + $response->assertStatus(200); + $response->assertJson(['status' => 'success']); + } +}