feat: subscriptions
CI / 🧪 Tests Laravel (push) Successful in 2m48s
CI / 🐳 Build & Push Image (push) Successful in 3m0s

This commit is contained in:
2026-08-07 11:53:46 +02:00
parent 99cb0e63e6
commit 2ece4b6e3e
51 changed files with 1489 additions and 254 deletions
+17 -15
View File
@@ -1,5 +1,6 @@
<?php
use App\Enums\BillingProductPurpose;
use App\Enums\CreditProductType;
use App\Models\CreditProduct;
use App\Models\User;
@@ -8,44 +9,45 @@ use Laravel\Sanctum\Sanctum;
uses(RefreshDatabase::class);
it('lists active credit products ordered for the mobile app', function () {
it('lists the subscription and certification offers for the mobile app', function () {
Sanctum::actingAs(User::factory()->create());
CreditProduct::create([
'name' => 'Pack 10',
'name' => 'Certification',
'type' => CreditProductType::ONE_TIME,
'credits' => 10,
'amount' => 499,
'purpose' => BillingProductPurpose::CERTIFICATION,
'credits' => 0,
'amount' => 1999,
'currency' => 'eur',
'stripe_price_id' => 'price_pack_10',
'stripe_price_id' => 'price_certification',
'sort_order' => 20,
]);
CreditProduct::create([
'name' => 'Mensuel 30',
'name' => 'Bowli Plus',
'type' => CreditProductType::MONTHLY,
'credits' => 30,
'purpose' => BillingProductPurpose::SUBSCRIPTION,
'credits' => 0,
'amount' => 999,
'currency' => 'eur',
'stripe_price_id' => 'price_monthly_30',
'stripe_price_id' => 'price_subscription',
'sort_order' => 10,
]);
CreditProduct::create([
'name' => 'Inactive',
'name' => 'Ancien pack',
'type' => CreditProductType::ONE_TIME,
'credits' => 5,
'amount' => 299,
'currency' => 'eur',
'stripe_price_id' => 'price_inactive',
'is_active' => false,
'stripe_price_id' => 'price_legacy',
]);
$this
->getJson('/api/billing/products')
->assertOk()
->assertJsonCount(2, 'data')
->assertJsonPath('data.0.name', 'Mensuel 30')
->assertJsonPath('data.0.type', CreditProductType::MONTHLY->value)
->assertJsonPath('data.0.credits', 30)
->assertJsonPath('data.0.name', 'Bowli Plus')
->assertJsonPath('data.0.purpose', BillingProductPurpose::SUBSCRIPTION->value)
->assertJsonPath('data.0.formattedAmount', '9,99 EUR')
->assertJsonPath('data.1.name', 'Pack 10');
->assertJsonPath('data.1.name', 'Certification')
->assertJsonPath('data.1.purpose', BillingProductPurpose::CERTIFICATION->value);
});