mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
144 lines
6.3 KiB
JavaScript
144 lines
6.3 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);
|
|
});
|
|
});
|
|
|
|
// ── 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);
|
|
});
|
|
});
|