import { describe, expect, it } from 'vitest' import { adminRoleAtLeast, entitlementFeatures, maxEntitlementTier, normalizeAdminRole, normalizeEntitlementTier, resolveEntitlement, } from '@d3ro/core/entitlement' import { Feature } from '@d3ro/core/types' describe('entitlement tier normalization', () => { it('maps cloud and desktop tiers onto the canonical set', () => { expect(normalizeEntitlementTier('free')).toBe('free') expect(normalizeEntitlementTier('pro')).toBe('pro') expect(normalizeEntitlementTier('pro_plus')).toBe('pro_plus') expect(normalizeEntitlementTier('team')).toBe('pro_plus') expect(normalizeEntitlementTier('enterprise')).toBe('pro_plus') }) it('falls back to free for unknown values', () => { expect(normalizeEntitlementTier(undefined)).toBe('free') expect(normalizeEntitlementTier(42)).toBe('free') expect(normalizeEntitlementTier('vip')).toBe('free') }) it('picks the higher tier', () => { expect(maxEntitlementTier('free', 'pro')).toBe('pro') expect(maxEntitlementTier('pro_plus', 'pro')).toBe('pro_plus') expect(maxEntitlementTier('free', 'free')).toBe('free') }) }) describe('admin role normalization', () => { it('normalizes .NET and Supabase spellings', () => { expect(normalizeAdminRole('SuperAdmin')).toBe('superadmin') expect(normalizeAdminRole('super_admin')).toBe('superadmin') expect(normalizeAdminRole('admin')).toBe('admin') expect(normalizeAdminRole('Manager')).toBe('manager') expect(normalizeAdminRole('LegacyDisabled')).toBe('user') expect(normalizeAdminRole(undefined)).toBe('user') }) it('compares roles by rank', () => { expect(adminRoleAtLeast('admin', 'manager')).toBe(true) expect(adminRoleAtLeast('manager', 'admin')).toBe(false) expect(adminRoleAtLeast('superadmin', 'superadmin')).toBe(true) }) }) describe('resolveEntitlement', () => { it('takes the highest paid tier across sources', () => { const snapshot = resolveEntitlement({ subscriptionTier: 'free', licenseTier: 'pro_plus' }) expect(snapshot.tier).toBe('pro_plus') expect(snapshot.licenseTier).toBe('pro_plus') expect(snapshot.adFree).toBe(true) expect(snapshot.features).toContain(Feature.TEAM_WORKSPACE) }) it('does not downgrade a paid subscription with a stale free license', () => { const snapshot = resolveEntitlement({ subscriptionTier: 'pro', licenseTier: 'free' }) expect(snapshot.tier).toBe('pro') expect(snapshot.source).toBe('supabase') }) it('collapses an expired period to free', () => { const snapshot = resolveEntitlement({ subscriptionTier: 'pro_plus', expiresAt: Date.now() - 1000, }) expect(snapshot.tier).toBe('free') expect(snapshot.adFree).toBe(false) expect(snapshot.features).not.toContain(Feature.TEAM_WORKSPACE) }) it('prefers the Supabase role over the .NET role for admin capabilities', () => { const snapshot = resolveEntitlement({ dotnetRole: 'SuperAdmin', supabaseRole: 'manager' }) expect(snapshot.adminRole).toBe('manager') expect(snapshot.adminCapabilities).toEqual({ canManage: true, canAdmin: false, canSuperAdmin: false, }) }) it('reports no source when nothing is provided', () => { const snapshot = resolveEntitlement() expect(snapshot.tier).toBe('free') expect(snapshot.adminRole).toBe('user') expect(snapshot.source).toBe('none') }) it('grants the team feature only to paid tiers', () => { expect(entitlementFeatures('free')).not.toContain(Feature.TEAM_WORKSPACE) expect(entitlementFeatures('pro')).toContain(Feature.TEAM_WORKSPACE) expect(entitlementFeatures('free')).toContain(Feature.DICTATION) }) })