import { TIER_LEVELS, FEATURE_TIERS, VEHICLE_LIMITS, getTierLevel, canAccessFeature, getRequiredTier, getFeatureConfig, getAllFeatureConfigs, getVehicleLimit, canAddVehicle, getVehicleLimitConfig, } from '../feature-tiers'; describe('feature-tiers', () => { describe('TIER_LEVELS', () => { it('defines correct tier hierarchy', () => { expect(TIER_LEVELS.free).toBe(0); expect(TIER_LEVELS.pro).toBe(1); expect(TIER_LEVELS.enterprise).toBe(2); }); it('enterprise > pro > free', () => { expect(TIER_LEVELS.enterprise).toBeGreaterThan(TIER_LEVELS.pro); expect(TIER_LEVELS.pro).toBeGreaterThan(TIER_LEVELS.free); }); }); describe('FEATURE_TIERS', () => { it('includes scanMaintenanceSchedule feature', () => { const feature = FEATURE_TIERS['document.scanMaintenanceSchedule']; expect(feature).toBeDefined(); expect(feature.minTier).toBe('pro'); expect(feature.name).toBe('Scan for Maintenance Schedule'); expect(feature.upgradePrompt).toBeTruthy(); }); it('includes fuelLog.receiptScan feature', () => { const feature = FEATURE_TIERS['fuelLog.receiptScan']; expect(feature).toBeDefined(); expect(feature.minTier).toBe('pro'); expect(feature.name).toBe('Receipt Scan'); expect(feature.upgradePrompt).toBeTruthy(); }); }); describe('canAccessFeature - fuelLog.receiptScan', () => { const featureKey = 'fuelLog.receiptScan'; it('denies access for free tier user', () => { expect(canAccessFeature('free', featureKey)).toBe(false); }); it('allows access for pro tier user', () => { expect(canAccessFeature('pro', featureKey)).toBe(true); }); it('allows access for enterprise tier user (inherits pro)', () => { expect(canAccessFeature('enterprise', featureKey)).toBe(true); }); }); describe('getTierLevel', () => { it('returns correct level for each tier', () => { expect(getTierLevel('free')).toBe(0); expect(getTierLevel('pro')).toBe(1); expect(getTierLevel('enterprise')).toBe(2); }); it('returns 0 for unknown tier', () => { expect(getTierLevel('unknown' as any)).toBe(0); }); }); describe('canAccessFeature', () => { const featureKey = 'document.scanMaintenanceSchedule'; it('denies access for free tier to pro feature', () => { expect(canAccessFeature('free', featureKey)).toBe(false); }); it('allows access for pro tier to pro feature', () => { expect(canAccessFeature('pro', featureKey)).toBe(true); }); it('allows access for enterprise tier to pro feature (inheritance)', () => { expect(canAccessFeature('enterprise', featureKey)).toBe(true); }); it('allows access for unknown feature (fail open)', () => { expect(canAccessFeature('free', 'unknown.feature')).toBe(true); expect(canAccessFeature('pro', 'unknown.feature')).toBe(true); expect(canAccessFeature('enterprise', 'unknown.feature')).toBe(true); }); }); describe('getRequiredTier', () => { it('returns required tier for known feature', () => { expect(getRequiredTier('document.scanMaintenanceSchedule')).toBe('pro'); }); it('returns null for unknown feature', () => { expect(getRequiredTier('unknown.feature')).toBeNull(); }); }); describe('getFeatureConfig', () => { it('returns full config for known feature', () => { const config = getFeatureConfig('document.scanMaintenanceSchedule'); expect(config).toEqual({ minTier: 'pro', name: 'Scan for Maintenance Schedule', upgradePrompt: expect.any(String), }); }); it('returns undefined for unknown feature', () => { expect(getFeatureConfig('unknown.feature')).toBeUndefined(); }); }); describe('getAllFeatureConfigs', () => { it('returns copy of all feature configs', () => { const configs = getAllFeatureConfigs(); expect(configs['document.scanMaintenanceSchedule']).toBeDefined(); // Verify it's a copy, not the original configs['test'] = { minTier: 'free', name: 'test', upgradePrompt: '' }; expect(FEATURE_TIERS['test' as keyof typeof FEATURE_TIERS]).toBeUndefined(); }); }); describe('VEHICLE_LIMITS', () => { it('defines correct limits for each tier', () => { expect(VEHICLE_LIMITS.free).toBe(2); expect(VEHICLE_LIMITS.pro).toBe(5); expect(VEHICLE_LIMITS.enterprise).toBeNull(); }); }); describe('getVehicleLimit', () => { it('returns 2 for free tier', () => { expect(getVehicleLimit('free')).toBe(2); }); it('returns 5 for pro tier', () => { expect(getVehicleLimit('pro')).toBe(5); }); it('returns null for enterprise tier (unlimited)', () => { expect(getVehicleLimit('enterprise')).toBeNull(); }); }); describe('canAddVehicle', () => { describe('free tier (limit 2)', () => { it('returns true when below limit', () => { expect(canAddVehicle('free', 0)).toBe(true); expect(canAddVehicle('free', 1)).toBe(true); }); it('returns false when at limit', () => { expect(canAddVehicle('free', 2)).toBe(false); }); it('returns false when over limit', () => { expect(canAddVehicle('free', 3)).toBe(false); }); }); describe('pro tier (limit 5)', () => { it('returns true when below limit', () => { expect(canAddVehicle('pro', 0)).toBe(true); expect(canAddVehicle('pro', 4)).toBe(true); }); it('returns false when at limit', () => { expect(canAddVehicle('pro', 5)).toBe(false); }); it('returns false when over limit', () => { expect(canAddVehicle('pro', 6)).toBe(false); }); }); describe('enterprise tier (unlimited)', () => { it('always returns true regardless of count', () => { expect(canAddVehicle('enterprise', 0)).toBe(true); expect(canAddVehicle('enterprise', 100)).toBe(true); expect(canAddVehicle('enterprise', 999999)).toBe(true); }); }); }); describe('getVehicleLimitConfig', () => { it('returns correct config for free tier', () => { const config = getVehicleLimitConfig('free'); expect(config.limit).toBe(2); expect(config.tier).toBe('free'); expect(config.upgradePrompt).toContain('Free tier is limited to 2 vehicles'); expect(config.upgradePrompt).toContain('Pro'); expect(config.upgradePrompt).toContain('Enterprise'); }); it('returns correct config for pro tier', () => { const config = getVehicleLimitConfig('pro'); expect(config.limit).toBe(5); expect(config.tier).toBe('pro'); expect(config.upgradePrompt).toContain('Pro tier is limited to 5 vehicles'); expect(config.upgradePrompt).toContain('Enterprise'); }); it('returns correct config for enterprise tier', () => { const config = getVehicleLimitConfig('enterprise'); expect(config.limit).toBeNull(); expect(config.tier).toBe('enterprise'); expect(config.upgradePrompt).toBeTruthy(); }); it('provides default upgradePrompt fallback', () => { const config = getVehicleLimitConfig('enterprise'); expect(config.upgradePrompt).toBe('Upgrade to access additional vehicles.'); }); }); });