mirror of
https://github.com/anikeen-com/id.git
synced 2026-11-04 22:59:41 +00:00
Start subscriptions with a free trial
trial_days, trial_ends_at and trial_once when creating subscriptions (app and user token) and per subscription of checkout sessions. isTrial() on subscriptions, the subscription.trial_will_end event type, and the trial_already_used error code in the docs.
This commit is contained in:
10 files changed
+130
-9
No files matched your search
@@ -174,6 +174,35 @@ class AppSubscriptionsTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function test_a_subscription_starts_with_a_free_trial(): void
|
||||
{
|
||||
$this->respond(201, $this->subscription());
|
||||
$this->respond(200, $this->subscription(['active' => true, 'autorenew' => true, 'status' => 'trial', 'starts_at' => '2026-11-04T10:00:00+00:00', 'trial_ends_at' => date(DATE_ATOM, time() + 14 * 86400)]));
|
||||
|
||||
$subscription = $this->owner()->appSubscriptions()->create(['group' => 'team-1', 'name' => 'Pro', 'unit' => 'month', 'price' => '9.99', 'trial_days' => 14, 'trial_once' => true]);
|
||||
$subscription->checkout();
|
||||
|
||||
$this->assertSame(['group' => 'team-1', 'name' => 'Pro', 'unit' => 'month', 'price' => '9.99', 'trial_days' => 14, 'trial_once' => true, 'user_id' => '01JUSER'], $this->sentJson(0));
|
||||
$this->assertTrue($subscription->isTrial());
|
||||
$this->assertTrue($subscription->isActive());
|
||||
}
|
||||
|
||||
public function test_a_used_trial_is_refused_on_checkout(): void
|
||||
{
|
||||
$this->respond(201, $this->subscription());
|
||||
$this->respond(409, ['message' => 'The user already had a free trial.', 'error' => 'trial_already_used']);
|
||||
|
||||
$subscription = $this->owner()->appSubscriptions()->create(['name' => 'Pro', 'unit' => 'month', 'price' => '9.99', 'trial_ends_at' => '2026-12-01T00:00:00+01:00', 'trial_once' => true]);
|
||||
|
||||
try {
|
||||
$subscription->checkout();
|
||||
$this->fail('Expected an ApiException.');
|
||||
} catch (ApiException $e) {
|
||||
$this->assertTrue($e->isConflict());
|
||||
$this->assertSame('trial_already_used', $e->error);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_a_missing_user_id_is_reported(): void
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
@@ -139,6 +139,20 @@ class CheckoutSessionsTest extends TestCase
|
||||
$this->assertNull($user->checkoutSessions()->find('unknown'));
|
||||
}
|
||||
|
||||
public function test_session_subscriptions_carry_a_free_trial(): void
|
||||
{
|
||||
$this->respond(201, $this->sessionData());
|
||||
|
||||
$this->owner()->appCheckoutSessions()->create(['subscriptions' => [
|
||||
['group' => 'team-1', 'name' => 'Pro', 'unit' => 'month', 'price' => '9.99', 'trial_days' => 14, 'trial_once' => true],
|
||||
['group' => 'team-1', 'name' => 'Backup', 'unit' => 'month', 'price' => '1.99', 'trial_ends_at' => '2026-12-01T00:00:00+00:00'],
|
||||
]]);
|
||||
|
||||
$this->assertSame(14, $this->sentJson(0)['subscriptions'][0]['trial_days']);
|
||||
$this->assertTrue($this->sentJson(0)['subscriptions'][0]['trial_once']);
|
||||
$this->assertSame('2026-12-01T00:00:00+00:00', $this->sentJson(0)['subscriptions'][1]['trial_ends_at']);
|
||||
}
|
||||
|
||||
public function test_nothing_is_requested_until_a_method_is_called(): void
|
||||
{
|
||||
$this->owner()->checkoutSessions();
|
||||
@@ -159,5 +173,6 @@ class CheckoutSessionsTest extends TestCase
|
||||
$this->assertSame(['01JS1', '01JS2'], $event['data']['object']['subscription_ids']);
|
||||
$this->assertContains('checkout.expired', EventType::all());
|
||||
$this->assertContains('subscription.activated', EventType::all());
|
||||
$this->assertContains('subscription.trial_will_end', EventType::all());
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ class SubscriptionStatusTest extends TestCase
|
||||
$this->assertSame($status, $resource->status());
|
||||
$this->assertSame($running, $resource->isActive());
|
||||
$this->assertSame($status === SubscriptionStatus::DRAFT, $resource->isDraft());
|
||||
$this->assertSame($status === SubscriptionStatus::TRIAL, $resource->isTrial());
|
||||
$this->assertSame($status === SubscriptionStatus::PAUSED, $resource->isPaused());
|
||||
$this->assertSame($status === SubscriptionStatus::CANCELLING, $resource->isCancelling());
|
||||
$this->assertSame($status === SubscriptionStatus::EXPIRED, $resource->isExpired());
|
||||
|
||||
Reference in new issue
Block a user