224 lines
7.0 KiB
TypeScript
224 lines
7.0 KiB
TypeScript
/**
|
|
* 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');
|
|
});
|
|
});
|
|
});
|