diff --git a/.github/workflows/pint.yml b/.github/workflows/pint.yml new file mode 100644 index 0000000..777f670 --- /dev/null +++ b/.github/workflows/pint.yml @@ -0,0 +1,38 @@ +name: Pint + +on: + push: + branches: + - master + - main + pull_request: + branches: + - master + - main + +jobs: + pint: + runs-on: ubuntu-latest + + name: Pint check + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv + coverage: none + + - name: Setup problem matchers + run: | + echo "::add-matcher::${{ runner.tool_cache }}/php.json" + + - name: Install dependencies + run: composer update --prefer-dist --no-interaction + + - name: Run Pint + run: vendor/bin/pint --test diff --git a/composer.json b/composer.json index f33afd9..c37cdd6 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,8 @@ "require-dev": { "phpunit/phpunit": "^11.0.1", "orchestra/testbench": "^9.16", - "juzaweb/core": "^5.0" + "juzaweb/core": "^5.0", + "laravel/pint": "^1.29" }, "autoload": { "psr-4": { diff --git a/database/Seeders/PaymentDatabaseSeeder.php b/database/Seeders/PaymentDatabaseSeeder.php index 1a0e01e..b1c93fb 100644 --- a/database/Seeders/PaymentDatabaseSeeder.php +++ b/database/Seeders/PaymentDatabaseSeeder.php @@ -2,8 +2,8 @@ namespace Juzaweb\Modules\Payment\Database\Seeders; -use Illuminate\Database\Seeder; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Seeder; class PaymentDatabaseSeeder extends Seeder { diff --git a/database/migrations/2025_08_02_053516_create_payment_methods_table.php b/database/migrations/2025_08_02_053516_create_payment_methods_table.php index b966fb8..de0e30f 100644 --- a/database/migrations/2025_08_02_053516_create_payment_methods_table.php +++ b/database/migrations/2025_08_02_053516_create_payment_methods_table.php @@ -1,8 +1,8 @@ '₫', ]; - $symbol = $symbols[$currency] ?? $currency . ' '; + $symbol = $symbols[$currency] ?? $currency.' '; // Format based on currency if ($currency === 'VND') { - return number_format($price, 0, '.', ',') . $symbol; + return number_format($price, 0, '.', ',').$symbol; } // Default format for USD, EUR, etc. - return $symbol . number_format($price, 2, '.', ','); + return $symbol.number_format($price, 2, '.', ','); } diff --git a/src/Contracts/ModuleHandlerInterface.php b/src/Contracts/ModuleHandlerInterface.php index 040f686..d3a0c2f 100644 --- a/src/Contracts/ModuleHandlerInterface.php +++ b/src/Contracts/ModuleHandlerInterface.php @@ -1,10 +1,12 @@ mapWithKeys(fn($case) => [$case->value => $case->label()]) + ->mapWithKeys(fn ($case) => [$case->value => $case->label()]) ->toArray(); } diff --git a/src/Enums/OrderPaymentStatus.php b/src/Enums/OrderPaymentStatus.php index 271c7e9..d1fa114 100644 --- a/src/Enums/OrderPaymentStatus.php +++ b/src/Enums/OrderPaymentStatus.php @@ -1,10 +1,12 @@ __('Pending'), self::COMPLETED => __('Paid'), }; diff --git a/src/Enums/PaymentHistoryStatus.php b/src/Enums/PaymentHistoryStatus.php index baa9e01..e05a8b2 100644 --- a/src/Enums/PaymentHistoryStatus.php +++ b/src/Enums/PaymentHistoryStatus.php @@ -1,10 +1,12 @@ $actor->id, 'created_type' => get_class($actor), @@ -55,7 +56,7 @@ function () use ($request) { $item = $cart['item']->load('orderable'); $cartModel = $cart['cart']->load('items.orderable'); - $subtotal = $cartModel->items->sum(fn($item) => $item->orderable->price * $item->quantity); + $subtotal = $cartModel->items->sum(fn ($item) => $item->orderable->price * $item->quantity); $itemTotal = $item->orderable->price * $item->quantity; return $this->success( @@ -84,13 +85,13 @@ public function remove(Request $request, string $itemId) $cart = Cart::find($cartId); - if (!$cart) { + if (! $cart) { return $this->error(__('Cart not found')); } $item = $cart->items()->where('id', $itemId)->first(); - if (!$item) { + if (! $item) { return $this->error(__('Item not found in cart')); } diff --git a/src/Http/Controllers/CheckoutController.php b/src/Http/Controllers/CheckoutController.php index 77270e0..2077199 100644 --- a/src/Http/Controllers/CheckoutController.php +++ b/src/Http/Controllers/CheckoutController.php @@ -3,9 +3,10 @@ /** * JUZAWEB CMS - Laravel CMS for Your Project * - * @package juzaweb/cms * @author The Anh Dang + * * @link https://cms.juzaweb.com + * * @license GNU V2 */ @@ -38,7 +39,7 @@ public function index(Request $request, string $module, string $cartId) $cart->load([ 'items.orderable' => function ($q) { $q->with(['media'])->withTranslation(); - } + }, ]); $user = $request->user(); @@ -64,7 +65,7 @@ public function orderCheckout(Request $request, string $orderId) $order->load([ 'items.orderable' => function ($q) { $q->with(['media'])->withTranslation(); - } + }, ]); $user = $order->creator; @@ -82,7 +83,7 @@ public function thankyou(Request $request, string $orderId) $order = Order::findOrFail($orderId); $order->load([ - 'items.orderable' => fn($q) => $q->withTranslation(), + 'items.orderable' => fn ($q) => $q->withTranslation(), ]); return view( diff --git a/src/Http/Controllers/MethodController.php b/src/Http/Controllers/MethodController.php index b1f7125..bc956e0 100644 --- a/src/Http/Controllers/MethodController.php +++ b/src/Http/Controllers/MethodController.php @@ -3,9 +3,10 @@ /** * JUZAWEB CMS - Laravel CMS for Your Project * - * @package juzaweb/cms * @author The Anh Dang + * * @link https://cms.juzaweb.com + * * @license GNU V2 */ @@ -53,7 +54,7 @@ public function create() $backUrl = action([static::class, 'index']); return view('payment::method.form', [ - 'model' => new PaymentMethod(), + 'model' => new PaymentMethod, 'action' => action([static::class, 'store']), 'locale' => $locale, 'backUrl' => $backUrl, diff --git a/src/Http/Controllers/PaymentController.php b/src/Http/Controllers/PaymentController.php index 20955e2..bca3684 100644 --- a/src/Http/Controllers/PaymentController.php +++ b/src/Http/Controllers/PaymentController.php @@ -36,7 +36,7 @@ public function checkout(CheckoutRequest $request, string $module) ->where('active', true) ->first(); - if (!$method) { + if (! $method) { return $this->error(__('Payment method not found!')); } @@ -247,6 +247,7 @@ function () use ($request, $handler, $module, $response) { ); } catch (PaymentException $e) { report($e); + return response( [ 'message' => $e->getMessage(), diff --git a/src/Http/DataTables/MethodsDataTable.php b/src/Http/DataTables/MethodsDataTable.php index d32f7f0..a8b2028 100644 --- a/src/Http/DataTables/MethodsDataTable.php +++ b/src/Http/DataTables/MethodsDataTable.php @@ -1,10 +1,12 @@ label() ?? $model->payment_status; - return '' . $label . ''; + + return ''.$label.''; } ); @@ -53,7 +53,8 @@ function (Order $model) { }; $label = $status?->label() ?? $model->delivery_status; - return '' . $label . ''; + + return ''.$label.''; } ); @@ -79,7 +80,7 @@ public function getColumns(): array Column::make('payment_method_name')->name(__('Payment Method')), Column::make('payment_status'), Column::make('delivery_status'), - Column::createdAt() + Column::createdAt(), ]; } diff --git a/src/Http/Requests/CartAddRequest.php b/src/Http/Requests/CartAddRequest.php index c972899..5970734 100644 --- a/src/Http/Requests/CartAddRequest.php +++ b/src/Http/Requests/CartAddRequest.php @@ -3,9 +3,10 @@ /** * JUZAWEB CMS - Laravel CMS for Your Project * - * @package juzaweb/cms * @author The Anh Dang + * * @link https://cms.juzaweb.com + * * @license GNU V2 */ diff --git a/src/Http/Requests/CheckoutRequest.php b/src/Http/Requests/CheckoutRequest.php index 0590db0..4ea3c8a 100644 --- a/src/Http/Requests/CheckoutRequest.php +++ b/src/Http/Requests/CheckoutRequest.php @@ -1,10 +1,12 @@ ['required', Rule::enum(OrderPaymentStatus::class)], - 'delivery_status' => ['required', Rule::enum(OrderDeliveryStatus::class)] - ]; + 'payment_status' => ['required', Rule::enum(OrderPaymentStatus::class)], + 'delivery_status' => ['required', Rule::enum(OrderDeliveryStatus::class)], + ]; } } diff --git a/src/Http/Requests/PaymentMethodRequest.php b/src/Http/Requests/PaymentMethodRequest.php index bb040fc..f25b4f3 100644 --- a/src/Http/Requests/PaymentMethodRequest.php +++ b/src/Http/Requests/PaymentMethodRequest.php @@ -1,9 +1,10 @@ [ - Rule::requiredIf(!$this->route('id')), - Rule::in(array_keys(PaymentManager::drivers())) + 'driver' => [ + Rule::requiredIf(! $this->route('id')), + Rule::in(array_keys(PaymentManager::drivers())), ], - 'name' => ['required', 'string', 'max:200'], - 'description' => ['nullable', 'string', 'max:500'], + 'name' => ['required', 'string', 'max:200'], + 'description' => ['nullable', 'string', 'max:500'], 'locale' => ['required', 'string', 'max:10', 'exists:languages,code'], - 'config' => ['required', 'array'], - 'active' => ['required', 'boolean'], - ]; + 'config' => ['required', 'array'], + 'active' => ['required', 'boolean'], + ]; } } diff --git a/src/Http/Requests/PaymentRequest.php b/src/Http/Requests/PaymentRequest.php index 2727e7a..8a2e19e 100644 --- a/src/Http/Requests/PaymentRequest.php +++ b/src/Http/Requests/PaymentRequest.php @@ -1,10 +1,12 @@ getTransactionReference(), $response->getRedirectUrl(), $response->getData() - )->setSuccessful($response->isSuccessful() && !$response->isRedirect()); + )->setSuccessful($response->isSuccessful() && ! $response->isRedirect()); } public function complete(array $params): CompleteResult @@ -75,12 +76,13 @@ public function handleWebhook(Request $request): ?CompleteResult { $payload = json_decode($request->getContent(), true); - if (!is_array($payload) || empty($payload['event_type'])) { + if (! is_array($payload) || empty($payload['event_type'])) { return null; } - if (!$this->verifyWebhookSignature($request, $payload)) { + if (! $this->verifyWebhookSignature($request, $payload)) { Log::error('PayPal Signature Verification Failed'); + return null; } @@ -126,8 +128,9 @@ protected function verifyWebhookSignature(Request $request, array $payload): boo $tokenRequest->initialize($gateway->getParameters()); $response = $tokenRequest->send(); - if (!$response->isSuccessful()) { - Log::error('PayPal Token Error: ' . $response->getMessage()); + if (! $response->isSuccessful()) { + Log::error('PayPal Token Error: '.$response->getMessage()); + return false; } @@ -140,7 +143,7 @@ protected function verifyWebhookSignature(Request $request, array $payload): boo 'transmission_sig' => $request->header('PAYPAL-TRANSMISSION-SIG'), 'transmission_time' => $request->header('PAYPAL-TRANSMISSION-TIME'), 'webhook_id' => $webhookId, - 'webhook_event' => $payload + 'webhook_event' => $payload, ]; $apiUrl = $isSandbox @@ -152,12 +155,14 @@ protected function verifyWebhookSignature(Request $request, array $payload): boo if ($verifyResponse->successful()) { $data = $verifyResponse->json(); + return isset($data['verification_status']) && $data['verification_status'] === 'SUCCESS'; } - Log::error('PayPal Verify Error: ' . $verifyResponse->body()); + Log::error('PayPal Verify Error: '.$verifyResponse->body()); } catch (\Exception $e) { - Log::error('PayPal Webhook Exception: ' . $e->getMessage()); + Log::error('PayPal Webhook Exception: '.$e->getMessage()); + return false; } diff --git a/src/Methods/PaymentGateway.php b/src/Methods/PaymentGateway.php index c4fb250..27a9721 100644 --- a/src/Methods/PaymentGateway.php +++ b/src/Methods/PaymentGateway.php @@ -1,10 +1,12 @@ getTransactionReference(), - $response->getRedirectUrl() . '/?embedded=true', + $response->getRedirectUrl().'/?embedded=true', $response->getData() ); } @@ -80,6 +80,7 @@ protected function createGateway(): GatewayInterface if (isset($this->config['sandbox']) && $this->config['sandbox']) { $gateway->setTestMode(true); } + return $gateway; } } diff --git a/src/Methods/Stripe.php b/src/Methods/Stripe.php index a0d7b87..418b68c 100644 --- a/src/Methods/Stripe.php +++ b/src/Methods/Stripe.php @@ -3,16 +3,16 @@ /** * JUZAWEB CMS - Laravel CMS for Your Project * - * @package juzaweb/cms * @author The Anh Dang + * * @link https://cms.juzaweb.com + * * @license GNU V2 */ namespace Juzaweb\Modules\Payment\Methods; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Log; use Juzaweb\Modules\Payment\Contracts\PaymentGatewayInterface; use Juzaweb\Modules\Payment\Exceptions\PaymentException; use Juzaweb\Modules\Payment\Services\CompleteResult; @@ -55,14 +55,14 @@ public function purchase(array $params): PurchaseResult $paymentIntentId, $confirmResponse->getRedirectUrl(), $confirmResponse->getData() - )->setSuccessful($confirmResponse->isSuccessful() && !$confirmResponse->isRedirect()); + )->setSuccessful($confirmResponse->isSuccessful() && ! $confirmResponse->isRedirect()); } return PurchaseResult::make( $response->getTransactionReference(), $response->getRedirectUrl(), $response->getData() - )->setSuccessful($response->isSuccessful() && !$response->isRedirect()); + )->setSuccessful($response->isSuccessful() && ! $response->isRedirect()); } public function complete(array $params): CompleteResult diff --git a/src/Models/Cart.php b/src/Models/Cart.php index 1eefd9e..a0ef3c6 100644 --- a/src/Models/Cart.php +++ b/src/Models/Cart.php @@ -11,7 +11,7 @@ class Cart extends Model { - use HasAPI, HasUuids, HasCreator, UsedInFrontend; + use HasAPI, HasCreator, HasUuids, UsedInFrontend; protected $table = 'carts'; @@ -33,13 +33,13 @@ public function scopeWhereInFrontend(Builder $builder, bool $cache = true): Buil $q->cacheFor(3600)->with(['orderable' => function ($q2) { $q2->with(['media'])->cacheFor(3600)->withTranslation(); }]); - } + }, ] ); } public function getTotalAmount() { - return $this->items->sum(fn($item) => $item->orderable->price * $item->quantity); + return $this->items->sum(fn ($item) => $item->orderable->price * $item->quantity); } } diff --git a/src/Models/CartItem.php b/src/Models/CartItem.php index b29962a..dcd4a91 100644 --- a/src/Models/CartItem.php +++ b/src/Models/CartItem.php @@ -3,9 +3,10 @@ /** * JUZAWEB CMS - Laravel CMS for Your Project * - * @package juzaweb/cms * @author The Anh Dang + * * @link https://cms.juzaweb.com + * * @license GNU V2 */ diff --git a/src/Models/Order.php b/src/Models/Order.php index 0303655..aa0a4f8 100644 --- a/src/Models/Order.php +++ b/src/Models/Order.php @@ -17,7 +17,7 @@ class Order extends Model implements Paymentable { - use HasAPI, HasCodeWithMonth, HasUuids, HasCreator; + use HasAPI, HasCodeWithMonth, HasCreator, HasUuids; protected $table = 'orders'; diff --git a/src/Models/OrderItem.php b/src/Models/OrderItem.php index 8dae90a..ff1800c 100644 --- a/src/Models/OrderItem.php +++ b/src/Models/OrderItem.php @@ -1,10 +1,12 @@ app[PaymentManager::class]->registerDriver( 'PayPal', - fn() => new PaymentDriverAdapter( + fn () => new PaymentDriverAdapter( Methods\PayPal::class, [ 'sandbox_client_id' => __('Sandbox Client ID'), @@ -54,7 +52,7 @@ public function boot(): void $this->app[PaymentManager::class]->registerDriver( 'Stripe', - fn() => new PaymentDriverAdapter( + fn () => new PaymentDriverAdapter( Methods\Stripe::class, [ 'sandbox_publishable_key' => __('Sandbox Publishable key'), @@ -69,7 +67,7 @@ public function boot(): void $this->app[PaymentManager::class]->registerDriver( 'Custom', - fn() => new PaymentDriverAdapter( + fn () => new PaymentDriverAdapter( Methods\Custom::class, [] // No configuration needed ) @@ -78,8 +76,6 @@ public function boot(): void /** * Register the service provider. - * - * @return void */ public function register(): void { @@ -88,19 +84,19 @@ public function register(): void $this->registerTranslations(); $this->registerConfig(); $this->registerViews(); - $this->loadMigrationsFrom(__DIR__ . '/../../database/migrations'); + $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); $this->app->singleton( PaymentManager::class, function ($app) { - return new \Juzaweb\Modules\Payment\Services\PaymentManager(); + return new \Juzaweb\Modules\Payment\Services\PaymentManager; } ); } protected function registerHelpers(): void { - require_once __DIR__ . '/../../helpers/helpers.php'; + require_once __DIR__.'/../../helpers/helpers.php'; } protected function registerMenu(): void @@ -108,7 +104,7 @@ protected function registerMenu(): void Menu::make('orders', function () { return [ 'title' => __('Orders'), - 'icon' => 'fas fa-shopping-cart' + 'icon' => 'fas fa-shopping-cart', ]; }); @@ -122,38 +118,32 @@ protected function registerMenu(): void /** * Register config. - * - * @return void */ protected function registerConfig(): void { $this->publishes([ - __DIR__ . '/../../config/payment.php' => config_path('payment.php'), + __DIR__.'/../../config/payment.php' => config_path('payment.php'), ], 'config'); - $this->mergeConfigFrom(__DIR__ . '/../../config/payment.php', 'payment'); + $this->mergeConfigFrom(__DIR__.'/../../config/payment.php', 'payment'); } /** * Register translations. - * - * @return void */ protected function registerTranslations(): void { - $this->loadTranslationsFrom(__DIR__ . '/../resources/lang', 'payment'); - $this->loadJsonTranslationsFrom(__DIR__ . '/../resources/lang'); + $this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'payment'); + $this->loadJsonTranslationsFrom(__DIR__.'/../resources/lang'); } /** * Register views. - * - * @return void */ protected function registerViews(): void { $viewPath = resource_path('views/modules/payment'); - $sourcePath = __DIR__ . '/../resources/views'; + $sourcePath = __DIR__.'/../resources/views'; $this->publishes([$sourcePath => $viewPath], ['views', 'payment-module-views']); diff --git a/src/Providers/RouteServiceProvider.php b/src/Providers/RouteServiceProvider.php index bbfb62d..08facf0 100644 --- a/src/Providers/RouteServiceProvider.php +++ b/src/Providers/RouteServiceProvider.php @@ -10,8 +10,6 @@ class RouteServiceProvider extends ServiceProvider { /** * Define the routes for the application. - * - * @return void */ public function boot(): void { @@ -24,14 +22,14 @@ public function boot(): void Route::middleware(['admin']) ->prefix($adminPrefix) - ->group(__DIR__ . '/../routes/admin.php'); + ->group(__DIR__.'/../routes/admin.php'); Route::middleware(['theme']) ->prefix(Locale::setLocale()) - ->group(__DIR__ . '/../routes/web.php'); + ->group(__DIR__.'/../routes/web.php'); Route::middleware([]) - ->group(__DIR__ . '/../routes/webhook.php'); + ->group(__DIR__.'/../routes/webhook.php'); }); } } diff --git a/src/Rules/OrderableExists.php b/src/Rules/OrderableExists.php index 9550668..98afdc8 100644 --- a/src/Rules/OrderableExists.php +++ b/src/Rules/OrderableExists.php @@ -3,9 +3,10 @@ /** * JUZAWEB CMS - Laravel CMS for Your Project * - * @package juzaweb/cms * @author The Anh Dang + * * @link https://cms.juzaweb.com + * * @license GNU V2 */ @@ -28,12 +29,13 @@ public function __construct(string $orderableType) */ public function validate(string $attribute, mixed $value, Closure $fail): void { - if (!class_exists($this->orderableType)) { + if (! class_exists($this->orderableType)) { $fail(trans('ecommerce::validation.orderable_type_invalid')); + return; } - if (!$this->orderableType::where('id', $value)->exists()) { + if (! $this->orderableType::where('id', $value)->exists()) { $fail(trans('ecommerce::validation.orderable_not_found')); } } diff --git a/src/Services/CompleteResult.php b/src/Services/CompleteResult.php index 21f4036..29db2e8 100644 --- a/src/Services/CompleteResult.php +++ b/src/Services/CompleteResult.php @@ -1,10 +1,12 @@ where('active', true) ->first(); @@ -165,7 +166,7 @@ public function registerModule(string $name, ModuleHandlerInterface $handler): v public function drivers(): array { return collect(array_keys($this->drivers)) - ->mapWithKeys(fn($driver) => [ + ->mapWithKeys(fn ($driver) => [ $driver => title_from_key($driver), ]) ->all(); @@ -183,7 +184,7 @@ public function driver(string $name, array $config): Contracts\PaymentGatewayInt public function config(string $driver): array { - if (!isset($this->drivers[$driver])) { + if (! isset($this->drivers[$driver])) { throw new PaymentException("Payment driver [$driver] not registered."); } @@ -192,7 +193,7 @@ public function config(string $driver): array public function driverAdapter(string $name): PaymentDriverAdapter { - if (!isset($this->drivers[$name])) { + if (! isset($this->drivers[$name])) { throw new PaymentException("Payment driver [$name] not registered."); } @@ -214,9 +215,9 @@ public function renderConfig(string $driver, array $config = []): string )->render(); } - public function module(string $module): Contracts\ModuleHandlerInterface + public function module(string $module): ModuleHandlerInterface { - if (!isset($this->modules[$module])) { + if (! isset($this->modules[$module])) { throw new PaymentException("Payment module [$module] not registered."); } diff --git a/src/Services/PaymentResult.php b/src/Services/PaymentResult.php index aad7abc..f0c0105 100644 --- a/src/Services/PaymentResult.php +++ b/src/Services/PaymentResult.php @@ -1,10 +1,12 @@ transactionId = $transactionId; $this->redirectUrl = $redirectUrl; diff --git a/src/Traits/HasPayment.php b/src/Traits/HasPayment.php index 21faa0c..3250de8 100644 --- a/src/Traits/HasPayment.php +++ b/src/Traits/HasPayment.php @@ -1,10 +1,12 @@ name('payment.checkout'); diff --git a/src/routes/webhook.php b/src/routes/webhook.php index 2c5764c..4045aa2 100644 --- a/src/routes/webhook.php +++ b/src/routes/webhook.php @@ -1,10 +1,12 @@ name('payment.webhook'); - \ No newline at end of file diff --git a/tests/Feature/MethodControllerTest.php b/tests/Feature/MethodControllerTest.php index 9ba9260..f219236 100644 --- a/tests/Feature/MethodControllerTest.php +++ b/tests/Feature/MethodControllerTest.php @@ -2,25 +2,28 @@ namespace Juzaweb\Modules\Payment\Tests\Feature; -use Juzaweb\Modules\Payment\Tests\TestCase; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Gate; use Juzaweb\Modules\Core\Models\User; use Juzaweb\Modules\Payment\Models\PaymentMethod; +use Juzaweb\Modules\Payment\Tests\TestCase; class MethodControllerTest extends TestCase { protected $user; + protected $baseUrl = 'admin/payment-methods'; protected function setUp(): void { parent::setUp(); - \Illuminate\Support\Facades\Gate::before(function ($user, $ability) { + Gate::before(function ($user, $ability) { return $user->isSuperAdmin() ? true : null; }); // Ensure language exists - \Illuminate\Support\Facades\DB::table('languages')->insertOrIgnore([ + DB::table('languages')->insertOrIgnore([ 'code' => 'en', 'name' => 'English', 'created_at' => now(), @@ -41,7 +44,7 @@ protected function setUp(): void $this->actingAs($this->user); } - public function testIndex() + public function test_index() { $response = $this->get($this->baseUrl); @@ -49,15 +52,15 @@ public function testIndex() $response->assertSee('Payment Methods'); } - public function testCreate() + public function test_create() { - $response = $this->get($this->baseUrl . '/create?locale=en¤t_locale=en'); + $response = $this->get($this->baseUrl.'/create?locale=en¤t_locale=en'); $response->assertStatus(200); $response->assertSee('Create Payment Method'); } - public function testStore() + public function test_store() { $response = $this->post($this->baseUrl, [ 'name' => 'Test Method', @@ -71,7 +74,7 @@ public function testStore() $this->assertDatabaseHas('payment_method_translations', ['name' => 'Test Method']); } - public function testEdit() + public function test_edit() { $method = new PaymentMethod([ 'driver' => 'PayPal', @@ -81,13 +84,13 @@ public function testEdit() $method->setAttribute('name', 'Edit Method'); $method->save(); - $response = $this->get($this->baseUrl . "/{$method->id}/edit?locale=en¤t_locale=en"); + $response = $this->get($this->baseUrl."/{$method->id}/edit?locale=en¤t_locale=en"); $response->assertStatus(200); $response->assertSee('Edit Payment Method'); } - public function testUpdate() + public function test_update() { $method = new PaymentMethod([ 'driver' => 'PayPal', @@ -97,7 +100,7 @@ public function testUpdate() $method->setAttribute('name', 'Update Method'); $method->save(); - $response = $this->put($this->baseUrl . "/{$method->id}", [ + $response = $this->put($this->baseUrl."/{$method->id}", [ 'name' => 'Updated Method', 'driver' => 'PayPal', 'locale' => 'en', @@ -109,9 +112,9 @@ public function testUpdate() $this->assertDatabaseHas('payment_method_translations', ['name' => 'Updated Method']); } - public function testGetData() + public function test_get_data() { - $response = $this->get($this->baseUrl . '/PayPal/get-data'); + $response = $this->get($this->baseUrl.'/PayPal/get-data'); $response->assertStatus(200); } diff --git a/tests/Feature/OrderRouteTest.php b/tests/Feature/OrderRouteTest.php index b712494..d97329e 100644 --- a/tests/Feature/OrderRouteTest.php +++ b/tests/Feature/OrderRouteTest.php @@ -2,11 +2,10 @@ namespace Juzaweb\Modules\Payment\Tests\Feature; -use Juzaweb\Modules\Payment\Tests\TestCase; +use Illuminate\Support\Str; use Juzaweb\Modules\Core\Models\User; use Juzaweb\Modules\Payment\Models\Order; -use Illuminate\Support\Str; -use Illuminate\Support\Facades\URL; +use Juzaweb\Modules\Payment\Tests\TestCase; class OrderRouteTest extends TestCase { @@ -34,13 +33,13 @@ public function test_create_route_does_not_exist() ); $indexUrl = route('admin.orders.index'); - $createUrl = $indexUrl . '/create'; + $createUrl = $indexUrl.'/create'; $response = $this->get($createUrl); // It returns 405 because it likely matches 'admin.orders.show' (GET {id}) // and 'create' is treated as ID, but then fails or method handling mismatch. // We just want to ensure it's not 200 OK form. - $this->assertTrue(in_array($response->status(), [404, 405]), 'Status should be 404 or 405, got ' . $response->status()); + $this->assertTrue(in_array($response->status(), [404, 405]), 'Status should be 404 or 405, got '.$response->status()); } public function test_store_route_does_not_exist() @@ -58,7 +57,7 @@ public function test_store_route_does_not_exist() public function test_edit_route_exists() { $order = Order::create([ - 'code' => 'ORD-' . Str::random(10), + 'code' => 'ORD-'.Str::random(10), 'quantity' => 1, 'total_price' => 100, 'total' => 100, @@ -72,7 +71,7 @@ public function test_edit_route_exists() public function test_update_route_exists() { $order = Order::create([ - 'code' => 'ORD-' . Str::random(10), + 'code' => 'ORD-'.Str::random(10), 'quantity' => 1, 'total_price' => 100, 'total' => 100, @@ -90,7 +89,7 @@ public function test_update_route_exists() public function test_destroy_route_not_implemented() { $order = Order::create([ - 'code' => 'ORD-' . Str::random(10), + 'code' => 'ORD-'.Str::random(10), 'quantity' => 1, 'total_price' => 100, 'total' => 100, diff --git a/tests/Feature/PaymentRouteTest.php b/tests/Feature/PaymentRouteTest.php index 2fd9b40..bb9a801 100644 --- a/tests/Feature/PaymentRouteTest.php +++ b/tests/Feature/PaymentRouteTest.php @@ -3,28 +3,35 @@ namespace Juzaweb\Modules\Payment\Tests\Feature; use Illuminate\Support\Facades\Request; -use Juzaweb\Modules\Payment\Tests\TestCase; +use Illuminate\Support\Facades\Schema; +use Illuminate\Support\Str; +use Juzaweb\Modules\Core\Http\Middleware\MultipleLanguage; use Juzaweb\Modules\Core\Models\User; -use Juzaweb\Modules\Payment\Models\PaymentMethod; -use Juzaweb\Modules\Payment\Models\Order; -use Juzaweb\Modules\Payment\Facades\PaymentManager; +use Juzaweb\Modules\Core\Translations\Models\Language; use Juzaweb\Modules\Payment\Contracts\ModuleHandlerInterface; use Juzaweb\Modules\Payment\Contracts\PaymentGatewayInterface; +use Juzaweb\Modules\Payment\Enums\OrderPaymentStatus; +use Juzaweb\Modules\Payment\Enums\PaymentHistoryStatus; +use Juzaweb\Modules\Payment\Facades\PaymentManager; +use Juzaweb\Modules\Payment\Models\Order; +use Juzaweb\Modules\Payment\Models\PaymentHistory; +use Juzaweb\Modules\Payment\Models\PaymentMethod; +use Juzaweb\Modules\Payment\Services\CompleteResult; use Juzaweb\Modules\Payment\Services\PaymentDriverAdapter; use Juzaweb\Modules\Payment\Services\PurchaseResult; -use Juzaweb\Modules\Payment\Services\CompleteResult; +use Juzaweb\Modules\Payment\Tests\TestCase; use Mockery; -use Illuminate\Support\Str; -use Juzaweb\Modules\Payment\Enums\OrderPaymentStatus; -use Juzaweb\Modules\Payment\Models\PaymentHistory; -use Juzaweb\Modules\Payment\Enums\PaymentHistoryStatus; class PaymentRouteTest extends TestCase { protected $user; + protected $paymentMethod; + protected $order; + protected $moduleHandler; + protected $gateway; protected function setUp(): void @@ -33,31 +40,31 @@ protected function setUp(): void // Create mix manifest for payment module $path = public_path('modules/payment'); - if (!is_dir($path)) { + if (! is_dir($path)) { mkdir($path, 0777, true); } - if (!file_exists($path . '/mix-manifest.json')) { - file_put_contents($path . '/mix-manifest.json', '{}'); + if (! file_exists($path.'/mix-manifest.json')) { + file_put_contents($path.'/mix-manifest.json', '{}'); } $this->user = User::factory()->create(); $this->actingAs($this->user); // Define currentActor macro if not exists - if (!Request::hasMacro('currentActor')) { + 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) { + if (! Schema::hasColumn('languages', 'default')) { + Schema::table('languages', function ($table) { $table->boolean('default')->default(false); }); } // Seed default language - $language = \Juzaweb\Modules\Core\Translations\Models\Language::firstOrCreate( + $language = Language::firstOrCreate( ['code' => 'en'], ['name' => 'English'] ); @@ -68,13 +75,13 @@ protected function setUp(): void app()->setLocale('en'); $this->withoutMiddleware([ - \Juzaweb\Modules\Core\Http\Middleware\MultipleLanguage::class, + 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) { + $this->moduleHandler->shouldReceive('createOrder')->andReturnUsing(function ($params) { return $this->order; }); $this->moduleHandler->shouldReceive('success'); @@ -94,7 +101,7 @@ protected function setUp(): void $driverAdapter->shouldReceive('isReturnInEmbed')->andReturn(false); $driverAdapter->shouldReceive('getDriver')->andReturn('TestDriver'); - PaymentManager::registerDriver('TestDriver', fn() => $driverAdapter); + PaymentManager::registerDriver('TestDriver', fn () => $driverAdapter); // Create Payment Method $this->paymentMethod = PaymentMethod::create([ @@ -106,7 +113,7 @@ protected function setUp(): void // Create Order $this->order = Order::create([ - 'code' => 'ORD-' . Str::random(10), + 'code' => 'ORD-'.Str::random(10), 'quantity' => 1, 'total_price' => 100, 'total' => 100, @@ -180,7 +187,7 @@ public function test_return_route() $response = $this->getJson(route('payment.return', [ 'module' => 'test_module', - 'paymentHistoryId' => $paymentHistory->id + 'paymentHistoryId' => $paymentHistory->id, ])); $response->assertStatus(200); @@ -188,7 +195,7 @@ public function test_return_route() public function test_cancel_route() { - $paymentHistory = PaymentHistory::create([ + $paymentHistory = PaymentHistory::create([ 'method_id' => $this->paymentMethod->id, 'payment_method' => $this->paymentMethod->driver, 'module' => 'test_module', @@ -202,7 +209,7 @@ public function test_cancel_route() $response = $this->getJson(route('payment.cancel', [ 'module' => 'test_module', - 'paymentHistoryId' => $paymentHistory->id + 'paymentHistoryId' => $paymentHistory->id, ])); // Cancel route returns 422 warning response @@ -229,7 +236,7 @@ public function test_embed_route() $response = $this->get(route('payment.embed', [ 'module' => 'test_module', - 'paymentHistoryId' => $paymentHistory->id + 'paymentHistoryId' => $paymentHistory->id, ])); $response->assertStatus(200); @@ -251,7 +258,7 @@ public function test_status_route() $response = $this->getJson(route('payment.status', [ 'module' => 'test_module', - 'paymentHistoryId' => $paymentHistory->id + 'paymentHistoryId' => $paymentHistory->id, ])); $response->assertStatus(200); diff --git a/tests/TestCase.php b/tests/TestCase.php index c55e785..9856495 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,7 +2,31 @@ namespace Juzaweb\Modules\Payment\Tests; +use Illuminate\Foundation\Application; +use Juzaweb\Hooks\HooksServiceProvider; +use Juzaweb\Modules\Core\Contracts\ThemeSetting; +use Juzaweb\Modules\Core\Facades\Chart; +use Juzaweb\Modules\Core\Facades\Field; +use Juzaweb\Modules\Core\Facades\Menu; +use Juzaweb\Modules\Core\Facades\Module; +use Juzaweb\Modules\Core\Facades\PageBlock; +use Juzaweb\Modules\Core\Facades\PageTemplate; +use Juzaweb\Modules\Core\Facades\Sidebar; +use Juzaweb\Modules\Core\Facades\Theme; +use Juzaweb\Modules\Core\Facades\Widget; +use Juzaweb\Modules\Core\Models\User; +use Juzaweb\Modules\Core\Permissions\PermissionServiceProvider; +use Juzaweb\Modules\Core\Providers\CoreServiceProvider; +use Juzaweb\Modules\Core\Translations\TranslationsServiceProvider; +use Juzaweb\Modules\Payment\Providers\PaymentServiceProvider; +use Juzaweb\QueryCache\QueryCacheServiceProvider; use Orchestra\Testbench\TestCase as Orchestra; +use Pion\Laravel\ChunkUpload\Providers\ChunkUploadServiceProvider; +use Spatie\Activitylog\ActivitylogServiceProvider; +use Yajra\DataTables\ButtonsServiceProvider; +use Yajra\DataTables\DataTablesServiceProvider; +use Yajra\DataTables\Facades\DataTables; +use Yajra\DataTables\HtmlServiceProvider; abstract class TestCase extends Orchestra { @@ -15,7 +39,7 @@ protected function setUp(): void $this->createMixManifest(); // Create class aliases for backward compatibility - if (!class_exists('Juzaweb\Modules\Admin\Models\User')) { + if (! class_exists('Juzaweb\Modules\Admin\Models\User')) { class_alias( 'Juzaweb\Modules\Core\Models\User', 'Juzaweb\Modules\Admin\Models\User' @@ -24,7 +48,7 @@ class_alias( // Load and alias UserFactory if (class_exists('Juzaweb\\Modules\\Core\\Database\\Factories\\UserFactory')) { - if (!class_exists('Juzaweb\\Modules\\Admin\\Database\\Factories\\UserFactory')) { + if (! class_exists('Juzaweb\\Modules\\Admin\\Database\\Factories\\UserFactory')) { class_alias( 'Juzaweb\\Modules\\Core\\Database\\Factories\\UserFactory', 'Juzaweb\\Modules\\Admin\\Database\\Factories\\UserFactory' @@ -33,10 +57,10 @@ class_alias( } // Load and alias UserStatus enum - $enumPath = __DIR__ . '/Enums/UserStatus.php'; + $enumPath = __DIR__.'/Enums/UserStatus.php'; if (file_exists($enumPath)) { require_once $enumPath; - if (!enum_exists('Juzaweb\\Modules\\Admin\\Enums\\UserStatus')) { + if (! enum_exists('Juzaweb\\Modules\\Admin\\Enums\\UserStatus')) { class_alias( 'Juzaweb\\Modules\\Core\\Tests\\Enums\\UserStatus', 'Juzaweb\\Modules\\Admin\\Enums\\UserStatus' @@ -44,32 +68,32 @@ class_alias( } } - $this->app[\Juzaweb\Modules\Core\Contracts\ThemeSetting::class]->set('setup', 1); + $this->app[ThemeSetting::class]->set('setup', 1); } protected function createMixManifest(): void { $path = public_path('juzaweb'); - if (!is_dir($path)) { + if (! is_dir($path)) { mkdir($path, 0777, true); } - if (!file_exists($path . '/mix-manifest.json')) { - file_put_contents($path . '/mix-manifest.json', '{}'); + if (! file_exists($path.'/mix-manifest.json')) { + file_put_contents($path.'/mix-manifest.json', '{}'); } } protected function createDummyTheme(): void { - $path = __DIR__ . '/themes/itech'; - if (!is_dir($path)) { + $path = __DIR__.'/themes/itech'; + if (! is_dir($path)) { mkdir($path, 0777, true); } - if (!file_exists($path . '/theme.json')) { - file_put_contents($path . '/theme.json', json_encode([ - "name" => "itech", - "title" => "Itech Theme", - "version" => "1.0", - "require" => [] + if (! file_exists($path.'/theme.json')) { + file_put_contents($path.'/theme.json', json_encode([ + 'name' => 'itech', + 'title' => 'Itech Theme', + 'version' => '1.0', + 'require' => [], ])); } } @@ -77,57 +101,55 @@ protected function createDummyTheme(): void /** * Get package providers. * - * @param \Illuminate\Foundation\Application $app + * @param Application $app * @return array */ protected function getPackageProviders($app): array { return [ - \Juzaweb\Modules\Core\Providers\CoreServiceProvider::class, - \Juzaweb\QueryCache\QueryCacheServiceProvider::class, - \Spatie\Activitylog\ActivitylogServiceProvider::class, - \Juzaweb\Hooks\HooksServiceProvider::class, - \Juzaweb\Modules\Core\Translations\TranslationsServiceProvider::class, - \Juzaweb\Modules\Core\Permissions\PermissionServiceProvider::class, - \Pion\Laravel\ChunkUpload\Providers\ChunkUploadServiceProvider::class, - \Yajra\DataTables\DataTablesServiceProvider::class, - \Yajra\DataTables\ButtonsServiceProvider::class, - \Yajra\DataTables\HtmlServiceProvider::class, - \Juzaweb\Modules\Payment\Providers\PaymentServiceProvider::class, + CoreServiceProvider::class, + QueryCacheServiceProvider::class, + ActivitylogServiceProvider::class, + HooksServiceProvider::class, + TranslationsServiceProvider::class, + PermissionServiceProvider::class, + ChunkUploadServiceProvider::class, + DataTablesServiceProvider::class, + ButtonsServiceProvider::class, + HtmlServiceProvider::class, + PaymentServiceProvider::class, ]; } /** * Get package aliases. * - * @param \Illuminate\Foundation\Application $app - * @return array + * @param Application $app */ protected function getPackageAliases($app): array { return [ - 'Field' => \Juzaweb\Modules\Core\Facades\Field::class, - 'Module' => \Juzaweb\Modules\Core\Facades\Module::class, - 'Theme' => \Juzaweb\Modules\Core\Facades\Theme::class, - 'Widget' => \Juzaweb\Modules\Core\Facades\Widget::class, - 'Sidebar' => \Juzaweb\Modules\Core\Facades\Sidebar::class, - 'PageTemplate' => \Juzaweb\Modules\Core\Facades\PageTemplate::class, - 'PageBlock' => \Juzaweb\Modules\Core\Facades\PageBlock::class, - 'Chart' => \Juzaweb\Modules\Core\Facades\Chart::class, - 'DataTables' => \Yajra\DataTables\Facades\DataTables::class, - 'Menu' => \Juzaweb\Modules\Core\Facades\Menu::class, + 'Field' => Field::class, + 'Module' => Module::class, + 'Theme' => Theme::class, + 'Widget' => Widget::class, + 'Sidebar' => Sidebar::class, + 'PageTemplate' => PageTemplate::class, + 'PageBlock' => PageBlock::class, + 'Chart' => Chart::class, + 'DataTables' => DataTables::class, + 'Menu' => Menu::class, ]; } /** * Define environment setup. * - * @param \Illuminate\Foundation\Application $app - * @return void + * @param Application $app */ protected function getEnvironmentSetUp($app): void { - $app['config']->set('themes.path', __DIR__ . '/themes'); + $app['config']->set('themes.path', __DIR__.'/themes'); // Use MySQL if DB_CONNECTION is set (e.g., in CI), otherwise use SQLite $connection = env('DB_CONNECTION', 'sqlite'); @@ -150,9 +172,9 @@ protected function getEnvironmentSetUp($app): void // Setup default database to use sqlite :memory: $app['config']->set('database.default', 'testbench'); $app['config']->set('database.connections.testbench', [ - 'driver' => 'sqlite', + 'driver' => 'sqlite', 'database' => ':memory:', - 'prefix' => '', + 'prefix' => '', ]); } @@ -167,13 +189,11 @@ protected function getEnvironmentSetUp($app): void 'root' => storage_path('app/private'), ]); - $app['config']->set('auth.providers.users.model', \Juzaweb\Modules\Core\Models\User::class); + $app['config']->set('auth.providers.users.model', User::class); } /** * Define database migrations. - * - * @return void */ protected function defineDatabaseMigrations(): void { @@ -182,7 +202,7 @@ protected function defineDatabaseMigrations(): void $this->loadLaravelMigrations(['--database' => $connection]); // Load package migrations - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); + $this->loadMigrationsFrom(__DIR__.'/../database/migrations'); $this->artisan('migrate', ['--database' => $connection])->run(); } diff --git a/tests/Unit/PaymentManagerTest.php b/tests/Unit/PaymentManagerTest.php index 9fb260c..1f0b6ec 100644 --- a/tests/Unit/PaymentManagerTest.php +++ b/tests/Unit/PaymentManagerTest.php @@ -3,13 +3,12 @@ namespace Juzaweb\Modules\Payment\Tests\Unit; use Illuminate\Support\Facades\Event; +use Juzaweb\Modules\Admin\Models\User; use Juzaweb\Modules\Payment\Contracts\ModuleHandlerInterface; use Juzaweb\Modules\Payment\Contracts\PaymentGatewayInterface; use Juzaweb\Modules\Payment\Contracts\PaymentManager; -use Juzaweb\Modules\Payment\Contracts\Paymentable; use Juzaweb\Modules\Payment\Enums\PaymentHistoryStatus; use Juzaweb\Modules\Payment\Events\PaymentCancel; -use Juzaweb\Modules\Payment\Events\PaymentFail; use Juzaweb\Modules\Payment\Events\PaymentSuccess; use Juzaweb\Modules\Payment\Exceptions\PaymentException; use Juzaweb\Modules\Payment\Models\Order; @@ -19,7 +18,6 @@ use Juzaweb\Modules\Payment\Services\PurchaseResult; use Juzaweb\Modules\Payment\Tests\TestCase; use Mockery; -use Juzaweb\Modules\Admin\Models\User; class PaymentManagerTest extends TestCase { @@ -233,8 +231,8 @@ public function test_cancel_payment() Event::fake(); $manager = app(PaymentManager::class); - // Create User & Order - $user = User::create([ + // Create User & Order + $user = User::create([ 'name' => 'Test User 3', 'email' => 'test3@example.com', 'password' => bcrypt('password'),