$code, 'name' => 'Rsync Studio '.$edition.' '.(str_contains($code, 'annual') ? 'Annual' : 'Monthly'), 'edition' => $edition, 'activation_limit' => $limit, 'max_major_version' => 1, 'payment_provider' => 'paddle', 'external_product_id' => 'pro_'.strtolower($edition), 'external_price_id' => $price, 'active' => true, ]); } public function test_personal_subscription_is_upgraded_in_place(): void { config()->set('rsync-studio.paddle.personal_monthly_price_id', 'pri_personal_monthly'); config()->set('rsync-studio.paddle.professional_monthly_price_id', 'pri_professional_monthly'); $personal = $this->product('personal-monthly', 'Personal', 'pri_personal_monthly', 1); $professional = $this->product('professional-monthly', 'Professional', 'pri_professional_monthly', 3); $user = User::factory()->create(['email' => 'mark@example.com', 'email_verified_at' => now()]); $license = License::create([ 'license_product_id' => $personal->id, 'license_key_hash' => str_repeat('a', 64), 'license_key_last4' => 'TEST', 'customer_email' => $user->email, 'edition' => 'Personal', 'activation_limit' => 1, 'max_major_version' => 1, 'payment_provider' => 'paddle', 'external_subscription_id' => 'sub_test', 'external_price_id' => 'pri_personal_monthly', 'subscription_status' => 'active', ]); $this->mock(PaddleClient::class, function (MockInterface $mock) { $mock->shouldReceive('updateSubscriptionPrice')->once()->with('sub_test', 'pri_professional_monthly')->andReturn(['status' => 'active']); }); $this->actingAs($user)->post(route('portal.upgrade', $license))->assertRedirect(route('portal.show', $license)); $license->refresh(); $this->assertSame($professional->id, $license->license_product_id); $this->assertSame('Professional', $license->edition); $this->assertSame(3, $license->activation_limit); $this->assertSame('sub_test', $license->external_subscription_id); } }