feat: revenue cat
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
config()->set('billing.revenuecat.secret_key', 'rc-secret');
|
||||
config()->set('billing.revenuecat.subscription_entitlement', 'bowli Pro');
|
||||
config()->set('billing.revenuecat.certification_entitlement', 'certification');
|
||||
});
|
||||
|
||||
it('synchronizes a monthly subscription trial from RevenueCat', function () {
|
||||
$user = User::factory()->create();
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
Http::fake([
|
||||
"api.revenuecat.com/v1/subscribers/{$user->id}" => Http::response([
|
||||
'subscriber' => [
|
||||
'entitlements' => [
|
||||
'bowli Pro' => [
|
||||
'expires_date' => now()->addDays(7)->toISOString(),
|
||||
'grace_period_expires_date' => null,
|
||||
'product_identifier' => 'monthly',
|
||||
'purchase_date' => now()->toISOString(),
|
||||
],
|
||||
],
|
||||
'subscriptions' => [
|
||||
'monthly' => [
|
||||
'period_type' => 'trial',
|
||||
'store' => 'app_store',
|
||||
],
|
||||
],
|
||||
],
|
||||
]),
|
||||
]);
|
||||
|
||||
$this->postJson('/api/billing/sync')
|
||||
->assertOk()
|
||||
->assertJsonPath('data.hasActiveSubscription', true)
|
||||
->assertJsonPath('data.analysisAccessLevel', 'trial')
|
||||
->assertJsonPath('data.subscriptionProductId', 'monthly')
|
||||
->assertJsonPath('data.certificationPurchased', false);
|
||||
|
||||
expect($user->fresh()->subscription_is_trial)->toBeTrue()
|
||||
->and($user->fresh()->subscription_store)->toBe('app_store');
|
||||
|
||||
Http::assertSent(fn ($request): bool => $request->hasHeader('Authorization', 'Bearer rc-secret'));
|
||||
});
|
||||
|
||||
it('synchronizes annual access and the lifetime certification independently', function () {
|
||||
$user = User::factory()->create();
|
||||
Sanctum::actingAs($user);
|
||||
$certificationPurchasedAt = now()->subDay()->startOfSecond();
|
||||
|
||||
Http::fake([
|
||||
"api.revenuecat.com/v1/subscribers/{$user->id}" => Http::response([
|
||||
'subscriber' => [
|
||||
'entitlements' => [
|
||||
'bowli Pro' => [
|
||||
'expires_date' => now()->addYear()->toISOString(),
|
||||
'grace_period_expires_date' => null,
|
||||
'product_identifier' => 'yearly',
|
||||
'purchase_date' => now()->toISOString(),
|
||||
],
|
||||
'certification' => [
|
||||
'expires_date' => null,
|
||||
'grace_period_expires_date' => null,
|
||||
'product_identifier' => 'lifetime',
|
||||
'purchase_date' => $certificationPurchasedAt->toISOString(),
|
||||
],
|
||||
],
|
||||
'subscriptions' => [
|
||||
'yearly' => [
|
||||
'period_type' => 'normal',
|
||||
'store' => 'play_store',
|
||||
],
|
||||
],
|
||||
],
|
||||
]),
|
||||
]);
|
||||
|
||||
$this->postJson('/api/billing/sync')
|
||||
->assertOk()
|
||||
->assertJsonPath('data.analysisAccessLevel', 'subscribed')
|
||||
->assertJsonPath('data.certificationPurchased', true);
|
||||
|
||||
$user->refresh();
|
||||
|
||||
expect($user->subscription_product_id)->toBe('yearly')
|
||||
->and($user->subscription_is_trial)->toBeFalse()
|
||||
->and($user->certification_purchased_at?->equalTo($certificationPurchasedAt))->toBeTrue();
|
||||
});
|
||||
|
||||
it('removes access when RevenueCat returns expired entitlements', function () {
|
||||
$user = User::factory()->create([
|
||||
'certification_purchased_at' => now()->subMonth(),
|
||||
'subscription_expires_at' => now()->addMonth(),
|
||||
'subscription_is_trial' => true,
|
||||
'subscription_product_id' => 'monthly',
|
||||
'subscription_store' => 'app_store',
|
||||
]);
|
||||
Sanctum::actingAs($user);
|
||||
|
||||
Http::fake([
|
||||
"api.revenuecat.com/v1/subscribers/{$user->id}" => Http::response([
|
||||
'subscriber' => [
|
||||
'entitlements' => [
|
||||
'bowli Pro' => [
|
||||
'expires_date' => now()->subDay()->toISOString(),
|
||||
'grace_period_expires_date' => null,
|
||||
'product_identifier' => 'monthly',
|
||||
],
|
||||
],
|
||||
'subscriptions' => [],
|
||||
],
|
||||
]),
|
||||
]);
|
||||
|
||||
$this->postJson('/api/billing/sync')
|
||||
->assertOk()
|
||||
->assertJsonPath('data.analysisAccessLevel', 'free')
|
||||
->assertJsonPath('data.hasActiveSubscription', false)
|
||||
->assertJsonPath('data.certificationPurchased', false);
|
||||
|
||||
expect($user->fresh()->subscription_product_id)->toBeNull()
|
||||
->and($user->fresh()->subscription_is_trial)->toBeFalse()
|
||||
->and($user->fresh()->certification_purchased_at)->toBeNull();
|
||||
});
|
||||
Reference in New Issue
Block a user