Files
fotospiel-app/tests/Feature/PurchaseTest.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];
}
}