116 lines
3.7 KiB
PHP
116 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Package;
|
|
use App\Models\Tenant;
|
|
use App\Models\User;
|
|
use App\Services\Paddle\PaddleCheckoutService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Mockery;
|
|
use Tests\TestCase;
|
|
|
|
class PurchaseTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
Mockery::close();
|
|
parent::tearDown();
|
|
}
|
|
|
|
public function test_create_paddle_checkout_requires_paddle_price(): void
|
|
{
|
|
[$tenant, $package] = $this->seedTenantWithPackage(includePaddlePrice: false);
|
|
$this->actingAs($tenant->user);
|
|
|
|
$response = $this->postJson('/paddle/create-checkout', [
|
|
'package_id' => $package->id,
|
|
]);
|
|
|
|
$response->assertStatus(422)
|
|
->assertJsonValidationErrors('package_id');
|
|
}
|
|
|
|
public function test_create_paddle_checkout_returns_checkout_url(): void
|
|
{
|
|
[$tenant, $package] = $this->seedTenantWithPackage(includePaddlePrice: true);
|
|
$this->actingAs($tenant->user);
|
|
|
|
$service = Mockery::mock(PaddleCheckoutService::class);
|
|
$service->shouldReceive('createCheckout')
|
|
->once()
|
|
->with(
|
|
Mockery::on(fn ($arg) => $arg instanceof Tenant && $arg->is($tenant)),
|
|
Mockery::on(fn ($arg) => $arg instanceof Package && $arg->is($package)),
|
|
Mockery::on(function ($options) {
|
|
return ($options['success_url'] ?? null) === null
|
|
&& ($options['return_url'] ?? null) === null
|
|
&& isset($options['metadata']['checkout_session_id']);
|
|
})
|
|
)
|
|
->andReturn([
|
|
'checkout_url' => 'https://paddle.test/checkout/abc',
|
|
]);
|
|
|
|
$this->app->instance(PaddleCheckoutService::class, $service);
|
|
|
|
$response = $this->postJson('/paddle/create-checkout', [
|
|
'package_id' => $package->id,
|
|
]);
|
|
|
|
$response->assertOk()
|
|
->assertJson([
|
|
'checkout_url' => 'https://paddle.test/checkout/abc',
|
|
]);
|
|
}
|
|
|
|
public function test_create_paddle_checkout_inline_returns_items(): void
|
|
{
|
|
[$tenant, $package] = $this->seedTenantWithPackage(includePaddlePrice: true);
|
|
$this->actingAs($tenant->user);
|
|
|
|
$service = Mockery::mock(PaddleCheckoutService::class);
|
|
$service->shouldNotReceive('createCheckout');
|
|
$this->app->instance(PaddleCheckoutService::class, $service);
|
|
|
|
$response = $this->postJson('/paddle/create-checkout', [
|
|
'package_id' => $package->id,
|
|
'inline' => true,
|
|
]);
|
|
|
|
$response->assertOk()
|
|
->assertJson([
|
|
'mode' => 'inline',
|
|
])
|
|
->assertJsonStructure([
|
|
'mode',
|
|
'items' => [
|
|
['priceId', 'quantity'],
|
|
],
|
|
'custom_data' => ['tenant_id', 'package_id', 'checkout_session_id'],
|
|
]);
|
|
|
|
$payload = $response->json();
|
|
$this->assertSame($package->paddle_price_id, $payload['items'][0]['priceId']);
|
|
$this->assertSame(1, $payload['items'][0]['quantity']);
|
|
}
|
|
|
|
private function seedTenantWithPackage(int $price = 10, string $type = 'endcustomer', bool $includePaddlePrice = true): array
|
|
{
|
|
$user = User::factory()->create(['email_verified_at' => now()]);
|
|
$tenant = Tenant::factory()->create(['user_id' => $user->id]);
|
|
|
|
$user->forceFill(['tenant_id' => $tenant->id])->save();
|
|
|
|
$package = Package::factory()->create([
|
|
'price' => $price,
|
|
'type' => $type,
|
|
'paddle_price_id' => $includePaddlePrice ? 'price_123' : null,
|
|
]);
|
|
|
|
return [$tenant, $package];
|
|
}
|
|
}
|