'use strict'; const { evaluateCourseAccess, TIER_RANK } = require('../../utils/accessPolicy.util'); // ── Helpers ─────────────────────────────────────────────────────────────────── function ctx(tier = 'free', access_rules = [], group_ids = []) { return { tier, access_rules, group_ids }; } function course(subscription = 'free') { return { subscription }; } // ── Free course is always accessible ───────────────────────────────────────── describe('free course (rank 0)', () => { test('free user can access free course', () => { expect(evaluateCourseAccess(ctx('free'), course('free'))).toEqual({ allowed: true, reason: null }); }); test('premium user can access free course', () => { expect(evaluateCourseAccess(ctx('premium'), course('free'))).toEqual({ allowed: true, reason: null }); }); test('free user with no rules can still access free course', () => { expect(evaluateCourseAccess(ctx('free', []), course('free'))).toEqual({ allowed: true, reason: null }); }); }); // ── No access_rules — fallback tier rank comparison ────────────────────────── describe('no access_rules (fallback mode)', () => { test('premium user can access premium course', () => { const result = evaluateCourseAccess(ctx('premium', []), course('premium'), TIER_RANK); expect(result).toEqual({ allowed: true, reason: null }); }); test('exclusive user can access exclusive course', () => { const result = evaluateCourseAccess(ctx('exclusive', []), course('exclusive'), TIER_RANK); expect(result).toEqual({ allowed: true, reason: null }); }); test('free user cannot access premium course', () => { const result = evaluateCourseAccess(ctx('free', []), course('premium'), TIER_RANK); expect(result).toEqual({ allowed: false, reason: 'tier_rank' }); }); test('premium user cannot access exclusive course', () => { const result = evaluateCourseAccess(ctx('premium', []), course('exclusive'), TIER_RANK); expect(result).toEqual({ allowed: false, reason: 'tier_rank' }); }); test('unknown course subscription slug → denied (safe default)', () => { const result = evaluateCourseAccess(ctx('exclusive', []), course('unknown-tier'), TIER_RANK); expect(result.allowed).toBe(false); }); }); // ── Rule: course_subscription_access ───────────────────────────────────────── describe('rule: course_subscription_access', () => { const rules = [{ type: 'course_subscription_access', levels: ['free', 'premium'] }]; test('plan covers premium → allowed', () => { const result = evaluateCourseAccess(ctx('premium', rules), course('premium'), TIER_RANK); expect(result.allowed).toBe(true); }); test('plan does not cover exclusive → denied', () => { const result = evaluateCourseAccess(ctx('exclusive', rules), course('exclusive'), TIER_RANK); expect(result).toEqual({ allowed: false, reason: 'subscription_access' }); }); }); // ── Rule: required_active_tier ──────────────────────────────────────────────── describe('rule: required_active_tier', () => { const rules = [{ type: 'required_active_tier', tier: 'premium' }]; test('premium user meets premium requirement → allowed', () => { const result = evaluateCourseAccess(ctx('premium', rules), course('premium'), TIER_RANK); expect(result.allowed).toBe(true); }); test('exclusive user exceeds premium requirement → allowed', () => { const result = evaluateCourseAccess(ctx('exclusive', rules), course('premium'), TIER_RANK); expect(result.allowed).toBe(true); }); test('free user fails premium requirement → denied', () => { const result = evaluateCourseAccess(ctx('free', rules), course('premium'), TIER_RANK); expect(result).toEqual({ allowed: false, reason: 'required_tier' }); }); test('unknown required tier slug → always denied', () => { const badRules = [{ type: 'required_active_tier', tier: 'ghost-tier' }]; const result = evaluateCourseAccess(ctx('exclusive', badRules), course('premium'), TIER_RANK); expect(result.allowed).toBe(false); }); }); // ── Rule: group_restriction ─────────────────────────────────────────────────── describe('rule: group_restriction', () => { const rules = [{ type: 'group_restriction', group_ids: [5, 10] }]; test('user in allowed group → allowed', () => { const result = evaluateCourseAccess(ctx('premium', rules, [10, 20]), course('premium'), TIER_RANK); expect(result.allowed).toBe(true); }); test('user not in any allowed group → denied', () => { const result = evaluateCourseAccess(ctx('premium', rules, [99]), course('premium'), TIER_RANK); expect(result).toEqual({ allowed: false, reason: 'group_restriction' }); }); test('empty group_ids on rule → no restriction (passes)', () => { const openRules = [{ type: 'group_restriction', group_ids: [] }]; const result = evaluateCourseAccess(ctx('premium', openRules, []), course('premium'), TIER_RANK); expect(result.allowed).toBe(true); }); }); // ── Rule: item_allowlist ─────────────────────────────────────────────────────── describe('rule: item_allowlist', () => { const rules = [ { type: 'course_subscription_access', levels: ['premium'] }, { type: 'item_allowlist', item_type: 'course', item_ids: [42, 99] }, ]; test('allowlisted exclusive course is granted even though the level-lock rule would block it', () => { const result = evaluateCourseAccess( ctx('premium', rules), course('exclusive'), TIER_RANK, { type: 'course', id: 42 } ); expect(result).toEqual({ allowed: true, reason: null }); }); test('matches item_ids as strings or numbers interchangeably', () => { const result = evaluateCourseAccess( ctx('premium', rules), course('exclusive'), TIER_RANK, { type: 'course', id: '99' } ); expect(result.allowed).toBe(true); }); test('non-allowlisted exclusive course still falls through to the level-lock rule and is denied', () => { const result = evaluateCourseAccess( ctx('premium', rules), course('exclusive'), TIER_RANK, { type: 'course', id: 7 } ); expect(result).toEqual({ allowed: false, reason: 'subscription_access' }); }); test('item_type must match — a unit id matching a course-scoped allowlist is not granted', () => { const result = evaluateCourseAccess( ctx('premium', rules), course('exclusive'), TIER_RANK, { type: 'unit', id: 42 } ); expect(result).toEqual({ allowed: false, reason: 'subscription_access' }); }); test('no itemMeta (or null id) — item_allowlist is skipped entirely, existing callers unaffected', () => { const result = evaluateCourseAccess(ctx('premium', rules), course('exclusive'), TIER_RANK); expect(result).toEqual({ allowed: false, reason: 'subscription_access' }); }); test('allowlisted item still requires nothing when premium content is requested normally', () => { const result = evaluateCourseAccess( ctx('premium', rules), course('premium'), TIER_RANK, { type: 'course', id: 1 } ); expect(result.allowed).toBe(true); }); }); // ── Multiple rules evaluated together ──────────────────────────────────────── describe('multiple rules', () => { test('fails if any one rule blocks', () => { const rules = [ { type: 'course_subscription_access', levels: ['premium', 'exclusive'] }, { type: 'required_active_tier', tier: 'premium' }, { type: 'group_restriction', group_ids: [7] }, ]; // All pass expect(evaluateCourseAccess(ctx('premium', rules, [7]), course('premium'), TIER_RANK).allowed).toBe(true); // Fails group_restriction expect(evaluateCourseAccess(ctx('premium', rules, [99]), course('premium'), TIER_RANK).allowed).toBe(false); // Fails required_active_tier expect(evaluateCourseAccess(ctx('free', rules, [7]), course('premium'), TIER_RANK).allowed).toBe(false); }); });