Files
motovaultpro/backend/src/core/config/tests/feature-tiers.test.ts
2026-02-11 09:29:48 -06:00

226 lines
7.2 KiB
TypeScript

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.');
});
});
});