getName())->toBe('activation_key'); expect($provider->isActive())->toBeTrue(); expect($provider->supportsRecurring())->toBeFalse(); expect($provider->supportsOneTime())->toBeTrue(); expect($provider->getSupportedCurrencies())->toBe(['USD']); }); test('can generate unique activation key', function () { $provider = new ActivationKeyProvider; $user = User::factory()->create(); $plan = Plan::factory()->create(['price' => 50.00]); $subscription = $provider->createSubscription($user, $plan); expect($subscription['provider_subscription_id'])->not->toBeEmpty(); expect($subscription['status'])->toBe('pending_activation'); expect($subscription['activation_key'])->not->toBeEmpty(); expect($subscription['activation_key'])->toStartWith('AK-'); expect($subscription['type'])->toBe('activation_key'); expect($subscription['plan_name'])->toBe($plan->name); expect($subscription['plan_price'])->toBe(50.00); }); test('can calculate fees correctly', function () { $provider = new ActivationKeyProvider; $fees = $provider->calculateFees(100.00); expect($fees['fixed_fee'])->toBe(0); expect($fees['percentage_fee'])->toBe(0); expect($fees['total_fee'])->toBe(0); expect($fees['net_amount'])->toBe(100.00); }); test('can get subscription details', function () { $provider = new ActivationKeyProvider; $user = User::factory()->create(); $plan = Plan::factory()->create(); $subscription = $provider->createSubscription($user, $plan); $details = $provider->getSubscriptionDetails($subscription['provider_subscription_id']); expect($details['id'])->toBe($subscription['provider_subscription_id']); expect($details['activation_key'])->toBe($subscription['activation_key']); expect($details['user_id'])->toBe($user->id); expect($details['price_id'])->toBe($plan->id); expect($details['is_activated'])->toBeFalse(); }); test('activation keys are not refundable', function () { $provider = new ActivationKeyProvider; expect(fn () => $provider->processRefund('test_id', 100.00, 'User requested')) ->toThrow(Exception::class, 'Activation keys are not refundable'); }); test('can get transaction history', function () { $provider = new ActivationKeyProvider; $user = User::factory()->create(); $plan = Plan::factory()->create(); // Create a few activation keys $provider->createSubscription($user, $plan); $provider->createSubscription($user, $plan); $history = $provider->getTransactionHistory($user); expect($history)->toBeArray(); expect($history)->toHaveCount(2); expect($history[0])->toHaveKey('activation_key'); expect($history[0])->toHaveKey('is_activated'); expect($history[0])->toHaveKey('created_at'); }); test('can get transaction history with filters', function () { $provider = new ActivationKeyProvider; $user = User::factory()->create(); $plan = Plan::factory()->create(); // Create activation keys $subscription1 = $provider->createSubscription($user, $plan); // Test filter for unactivated keys (all should be unactivated initially) $unactivatedHistory = $provider->getTransactionHistory($user, ['status' => 'unactivated']); expect($unactivatedHistory)->toHaveCount(1); expect($unactivatedHistory[0]['is_activated'])->toBeFalse(); }); test('can redeem activation key', function () { $provider = new ActivationKeyProvider; $user = User::factory()->create(); $plan = Plan::factory()->create(); // Create activation key $subscription = $provider->createSubscription($user, $plan); $activationKey = $subscription['activation_key']; // Redeem the key $result = $provider->redeemActivationKey($activationKey, $user); expect($result['success'])->toBeTrue(); expect($result['plan_name'])->toBe($plan->name); expect($result['message'])->toBe('Activation key redeemed successfully'); }); test('cannot redeem already activated key', function () { $provider = new ActivationKeyProvider; $user = User::factory()->create(); $plan = Plan::factory()->create(); // Create and redeem activation key $subscription = $provider->createSubscription($user, $plan); $activationKey = $subscription['activation_key']; $provider->redeemActivationKey($activationKey, $user); // Try to redeem again expect(fn () => $provider->redeemActivationKey($activationKey, $user)) ->throw(); }); test('can get configuration', function () { $config = [ 'key_prefix' => 'TEST-', 'key_length' => 16, 'expiration_days' => 365, ]; $provider = new ActivationKeyProvider($config); expect($provider->getConfiguration())->toHaveKey('key_prefix', 'TEST-'); expect($provider->getConfiguration())->toHaveKey('key_length', 16); expect($provider->getConfiguration())->toHaveKey('expiration_days', 365); }); test('webhook methods return expected values', function () { $provider = new ActivationKeyProvider; $request = new Illuminate\Http\Request; $webhookResult = $provider->processWebhook($request); expect($webhookResult['event_type'])->toBe('not_applicable'); expect($webhookResult['processed'])->toBeFalse(); expect($provider->validateWebhook($request))->toBeFalse(); }); test('customer portal returns dashboard', function () { $provider = new ActivationKeyProvider; $mockUser = new stdClass; $portal = $provider->createCustomerPortalSession($mockUser); expect($portal)->toHaveKey('portal_url'); expect($portal)->toHaveKey('message'); expect($portal['message'])->toBe('Activation keys are managed through your dashboard'); }); test('cannot update subscription plan', function () { $provider = new ActivationKeyProvider; $user = User::factory()->create(); $plan1 = Plan::factory()->create(); $plan2 = Plan::factory()->create(); $subscriptionData = $provider->createSubscription($user, $plan1); expect(fn () => $provider->updateSubscription( new class($subscriptionData['provider_subscription_id']) { public $provider_subscription_id; public function __construct($id) { $this->provider_subscription_id = $id; } }, $plan2 ))->toThrow('Activation keys do not support plan updates'); }); test('cannot pause or resume subscription', function () { $provider = new ActivationKeyProvider; $mockSubscription = new class { public $id = 1; }; expect($provider->pauseSubscription($mockSubscription))->toBeFalse(); expect($provider->resumeSubscription($mockSubscription))->toBeFalse(); }); test('does not support trials or coupons', function () { $provider = new ActivationKeyProvider; $mockSubscription = new class { public $id = 1; }; expect($provider->startTrial($mockSubscription, 7))->toBeFalse(); expect($provider->removeCoupon($mockSubscription))->toBeFalse(); expect(fn () => $provider->applyCoupon($mockSubscription, 'DISCOUNT10')) ->toThrow(Exception::class, 'Coupons not supported for activation keys'); }); test('upcoming invoice returns empty data', function () { $provider = new ActivationKeyProvider; $mockSubscription = new class { public $id = 1; }; $invoice = $provider->getUpcomingInvoice($mockSubscription); expect($invoice['amount_due'])->toBe(0); expect($invoice['currency'])->toBe('USD'); expect($invoice['next_payment_date'])->toBeNull(); }); test('has correct cancellation terms', function () { $provider = new ActivationKeyProvider; $mockSubscription = new class { public $id = 1; }; $terms = $provider->getCancellationTerms($mockSubscription); expect($terms['immediate_cancellation'])->toBeTrue(); expect($terms['refund_policy'])->toBe('non_refundable'); expect($terms['cancellation_effective'])->toBe('immediately'); expect($terms['billing_cycle_proration'])->toBeFalse(); }); test('can export subscription data', function () { $provider = new ActivationKeyProvider; $mockSubscription = new class { public $id = 1; public $provider_subscription_id = 'test_id'; public $provider_data = ['test' => 'data']; }; $data = $provider->exportSubscriptionData($mockSubscription); expect($data['provider'])->toBe('activation_key'); expect($data['provider_subscription_id'])->toBe('test_id'); expect($data['data'])->toBe(['test' => 'data']); }); test('cannot import subscription data', function () { $provider = new ActivationKeyProvider; $mockUser = new class { public $id = 1; }; $subscriptionData = ['provider' => 'activation_key', 'data' => []]; expect(fn () => $provider->importSubscriptionData($mockUser, $subscriptionData)) ->toThrow(Exception::class, 'Import to activation keys not implemented'); }); test('has correct method signatures', function () { $provider = new ActivationKeyProvider; // Test that all required methods exist and have correct signatures $reflection = new ReflectionClass($provider); $methods = [ 'getName' => 0, 'isActive' => 0, 'supportsRecurring' => 0, 'supportsOneTime' => 0, 'getSupportedCurrencies' => 0, 'calculateFees' => 1, 'createSubscription' => 3, 'cancelSubscription' => 2, 'updateSubscription' => 2, 'pauseSubscription' => 1, 'resumeSubscription' => 1, 'getSubscriptionDetails' => 1, 'createCheckoutSession' => 3, 'createCustomerPortalSession' => 1, 'processWebhook' => 1, 'validateWebhook' => 1, 'getConfiguration' => 0, 'syncSubscriptionStatus' => 1, 'getPaymentMethodDetails' => 1, 'processRefund' => 3, 'getTransactionHistory' => 2, 'getSubscriptionMetadata' => 1, 'updateSubscriptionMetadata' => 2, 'startTrial' => 2, 'applyCoupon' => 2, 'removeCoupon' => 1, 'getUpcomingInvoice' => 1, 'retryFailedPayment' => 1, 'canModifySubscription' => 1, 'getCancellationTerms' => 1, 'exportSubscriptionData' => 1, 'importSubscriptionData' => 2, 'redeemActivationKey' => 2, ]; foreach ($methods as $methodName => $expectedParams) { expect($reflection->hasMethod($methodName))->toBeTrue(); expect($reflection->getMethod($methodName)->getNumberOfParameters())->toBe($expectedParams); } });