Files
fotospiel-app/tests/Feature/PurchaseTest.php
Codex Agent 10c99de1e2
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Migrate billing from Paddle to Lemon Squeezy
2026-02-03 10:59:54 +01:00

105 lines
3.5 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Package;
use App\Models\Tenant;
use App\Models\User;
use App\Services\LemonSqueezy\LemonSqueezyCheckoutService;
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_lemonsqueezy_checkout_requires_variant(): void
{
[$tenant, $package] = $this->seedTenantWithPackage(includeVariant: false);
$this->actingAs($tenant->user);
$response = $this->postJson('/lemonsqueezy/create-checkout', [
'package_id' => $package->id,
'accepted_terms' => true,
]);
$response->assertStatus(422)
->assertJsonValidationErrors('package_id');
}
public function test_create_lemonsqueezy_checkout_returns_checkout_url(): void
{
[$tenant, $package] = $this->seedTenantWithPackage(includeVariant: true);
$this->actingAs($tenant->user);
$service = Mockery::mock(LemonSqueezyCheckoutService::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://checkout.lemonsqueezy.test/checkout/abc',
]);
$this->app->instance(LemonSqueezyCheckoutService::class, $service);
$response = $this->postJson('/lemonsqueezy/create-checkout', [
'package_id' => $package->id,
'accepted_terms' => true,
]);
$response->assertOk()
->assertJson([
'checkout_url' => 'https://checkout.lemonsqueezy.test/checkout/abc',
]);
}
public function test_create_lemonsqueezy_checkout_requires_terms(): void
{
[$tenant, $package] = $this->seedTenantWithPackage(includeVariant: true);
$this->actingAs($tenant->user);
$service = Mockery::mock(LemonSqueezyCheckoutService::class);
$service->shouldNotReceive('createCheckout');
$this->app->instance(LemonSqueezyCheckoutService::class, $service);
$response = $this->postJson('/lemonsqueezy/create-checkout', [
'package_id' => $package->id,
'accepted_terms' => false,
]);
$response->assertStatus(422)
->assertJsonValidationErrors('accepted_terms');
}
private function seedTenantWithPackage(int $price = 10, string $type = 'endcustomer', bool $includeVariant = 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,
'lemonsqueezy_variant_id' => $includeVariant ? 'variant_123' : null,
]);
return [$tenant, $package];
}
}