Files
starr-philproperties/tests/utils/accessPolicy.test.js
T
2026-08-01 23:02:31 +08:00

193 lines
8.5 KiB
JavaScript

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