/** * SubscriptionPlan Value Object Tests * * Unit tests for the SubscriptionPlan value object */ import { SubscriptionPlan } from './subscription-plan.vo'; describe('SubscriptionPlan Value Object', () => { describe('static factory methods', () => { it('should create FREE plan', () => { const plan = SubscriptionPlan.free(); expect(plan.value).toBe('FREE'); }); it('should create STARTER plan', () => { const plan = SubscriptionPlan.starter(); expect(plan.value).toBe('STARTER'); }); it('should create PRO plan', () => { const plan = SubscriptionPlan.pro(); expect(plan.value).toBe('PRO'); }); it('should create ENTERPRISE plan', () => { const plan = SubscriptionPlan.enterprise(); expect(plan.value).toBe('ENTERPRISE'); }); }); describe('create', () => { it('should create plan from valid type', () => { const plan = SubscriptionPlan.create('STARTER'); expect(plan.value).toBe('STARTER'); }); it('should throw for invalid plan type', () => { expect(() => SubscriptionPlan.create('INVALID' as any)).toThrow('Invalid subscription plan'); }); }); describe('fromString', () => { it('should create plan from lowercase string', () => { const plan = SubscriptionPlan.fromString('starter'); expect(plan.value).toBe('STARTER'); }); it('should throw for invalid string', () => { expect(() => SubscriptionPlan.fromString('invalid')).toThrow('Invalid subscription plan'); }); }); describe('maxLicenses', () => { it('should return 2 for FREE plan', () => { const plan = SubscriptionPlan.free(); expect(plan.maxLicenses).toBe(2); }); it('should return 5 for STARTER plan', () => { const plan = SubscriptionPlan.starter(); expect(plan.maxLicenses).toBe(5); }); it('should return 20 for PRO plan', () => { const plan = SubscriptionPlan.pro(); expect(plan.maxLicenses).toBe(20); }); it('should return -1 (unlimited) for ENTERPRISE plan', () => { const plan = SubscriptionPlan.enterprise(); expect(plan.maxLicenses).toBe(-1); }); }); describe('isUnlimited', () => { it('should return false for FREE plan', () => { expect(SubscriptionPlan.free().isUnlimited()).toBe(false); }); it('should return false for STARTER plan', () => { expect(SubscriptionPlan.starter().isUnlimited()).toBe(false); }); it('should return false for PRO plan', () => { expect(SubscriptionPlan.pro().isUnlimited()).toBe(false); }); it('should return true for ENTERPRISE plan', () => { expect(SubscriptionPlan.enterprise().isUnlimited()).toBe(true); }); }); describe('isPaid', () => { it('should return false for FREE plan', () => { expect(SubscriptionPlan.free().isPaid()).toBe(false); }); it('should return true for STARTER plan', () => { expect(SubscriptionPlan.starter().isPaid()).toBe(true); }); it('should return true for PRO plan', () => { expect(SubscriptionPlan.pro().isPaid()).toBe(true); }); it('should return true for ENTERPRISE plan', () => { expect(SubscriptionPlan.enterprise().isPaid()).toBe(true); }); }); describe('isFree', () => { it('should return true for FREE plan', () => { expect(SubscriptionPlan.free().isFree()).toBe(true); }); it('should return false for STARTER plan', () => { expect(SubscriptionPlan.starter().isFree()).toBe(false); }); }); describe('canAccommodateUsers', () => { it('should return true for FREE plan with 2 users', () => { expect(SubscriptionPlan.free().canAccommodateUsers(2)).toBe(true); }); it('should return false for FREE plan with 3 users', () => { expect(SubscriptionPlan.free().canAccommodateUsers(3)).toBe(false); }); it('should return true for STARTER plan with 5 users', () => { expect(SubscriptionPlan.starter().canAccommodateUsers(5)).toBe(true); }); it('should always return true for ENTERPRISE plan', () => { expect(SubscriptionPlan.enterprise().canAccommodateUsers(1000)).toBe(true); }); }); describe('canUpgradeTo', () => { it('should allow upgrade from FREE to STARTER', () => { expect(SubscriptionPlan.free().canUpgradeTo(SubscriptionPlan.starter())).toBe(true); }); it('should allow upgrade from FREE to PRO', () => { expect(SubscriptionPlan.free().canUpgradeTo(SubscriptionPlan.pro())).toBe(true); }); it('should allow upgrade from FREE to ENTERPRISE', () => { expect(SubscriptionPlan.free().canUpgradeTo(SubscriptionPlan.enterprise())).toBe(true); }); it('should allow upgrade from STARTER to PRO', () => { expect(SubscriptionPlan.starter().canUpgradeTo(SubscriptionPlan.pro())).toBe(true); }); it('should not allow downgrade from STARTER to FREE', () => { expect(SubscriptionPlan.starter().canUpgradeTo(SubscriptionPlan.free())).toBe(false); }); it('should not allow same plan upgrade', () => { expect(SubscriptionPlan.pro().canUpgradeTo(SubscriptionPlan.pro())).toBe(false); }); }); describe('canDowngradeTo', () => { it('should allow downgrade from STARTER to FREE when users fit', () => { expect(SubscriptionPlan.starter().canDowngradeTo(SubscriptionPlan.free(), 1)).toBe(true); }); it('should not allow downgrade from STARTER to FREE when users exceed', () => { expect(SubscriptionPlan.starter().canDowngradeTo(SubscriptionPlan.free(), 5)).toBe(false); }); it('should not allow upgrade via canDowngradeTo', () => { expect(SubscriptionPlan.free().canDowngradeTo(SubscriptionPlan.starter(), 1)).toBe(false); }); }); describe('plan details', () => { it('should return correct name for FREE plan', () => { expect(SubscriptionPlan.free().name).toBe('Free'); }); it('should return correct prices for STARTER plan', () => { const plan = SubscriptionPlan.starter(); expect(plan.monthlyPriceEur).toBe(49); expect(plan.yearlyPriceEur).toBe(470); }); it('should return features for PRO plan', () => { const plan = SubscriptionPlan.pro(); expect(plan.features).toContain('Up to 20 users'); expect(plan.features).toContain('API access'); }); }); describe('getAllPlans', () => { it('should return all 4 plans', () => { const plans = SubscriptionPlan.getAllPlans(); expect(plans).toHaveLength(4); expect(plans.map(p => p.value)).toEqual(['FREE', 'STARTER', 'PRO', 'ENTERPRISE']); }); }); describe('equals', () => { it('should return true for same plan', () => { expect(SubscriptionPlan.free().equals(SubscriptionPlan.free())).toBe(true); }); it('should return false for different plans', () => { expect(SubscriptionPlan.free().equals(SubscriptionPlan.starter())).toBe(false); }); }); describe('toString', () => { it('should return plan value as string', () => { expect(SubscriptionPlan.free().toString()).toBe('FREE'); expect(SubscriptionPlan.starter().toString()).toBe('STARTER'); }); }); });