mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
client and some admin new
Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
'use strict';
|
||||
|
||||
// ── Regression tests for item-specific entitlement (Tier Plans v2) ──────────
|
||||
// Before this change, canAccessCourse/canAccessUnit/canAccessLesson unlocked
|
||||
// content purely off tier RANK (any active Premium purchase unlocked every
|
||||
// premium-tagged course). Now a Tier Plan purchase only grants the EXACT
|
||||
// items its bundle contained at purchase time (recorded in
|
||||
// user_tier_grants) — plain tier rank alone must no longer be sufficient.
|
||||
// These tests exercise the real controller/model objects (Sequelize doesn't
|
||||
// connect until a query actually runs) and stub only the specific static
|
||||
// methods each scenario touches, via jest.spyOn.
|
||||
|
||||
const { Course } = require('../../models/courses/courses.associations');
|
||||
const { mdl_UserTierGrants } = require('../../models/tiers/tier.associations');
|
||||
const mdl_UserTiers = require('../../models/tiers/user_tiers.mdl');
|
||||
const mdl_TierCategories = require('../../models/tiers/tier_categories.mdl');
|
||||
const { mdl_UserGroupMembers } = require('../../models/users/user_groups.mdl');
|
||||
const mdl_Product = require('../../models/courses/products.mdl');
|
||||
const mdl_CoursePurchase = require('../../models/courses/course_purchases.mdl');
|
||||
|
||||
const { canAccessCourse } = require('../../controllers/client/courses.controller');
|
||||
|
||||
function mockActiveTierUnused() {
|
||||
jest.spyOn(mdl_UserTiers, 'findAll').mockResolvedValue([]);
|
||||
jest.spyOn(mdl_TierCategories, 'findAll').mockResolvedValue([]);
|
||||
jest.spyOn(mdl_UserGroupMembers, 'findAll').mockResolvedValue([]);
|
||||
}
|
||||
|
||||
afterEach(() => jest.restoreAllMocks());
|
||||
|
||||
describe('canAccessCourse() — item-specific entitlement', () => {
|
||||
test('free/ungated course is always accessible, no grant lookup needed', async () => {
|
||||
jest.spyOn(Course, 'findOne').mockResolvedValue({ subscription: 'free', status: 'published' });
|
||||
const grantSpy = jest.spyOn(mdl_UserTierGrants, 'findOne');
|
||||
|
||||
const result = await canAccessCourse(1, 100);
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(grantSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('unpublished course is never accessible regardless of entitlement', async () => {
|
||||
jest.spyOn(Course, 'findOne').mockResolvedValue({ subscription: 'premium', status: 'draft' });
|
||||
|
||||
const result = await canAccessCourse(1, 100);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
test('premium course with no grant, no purchase, no active tier → denied (tier rank alone no longer grants access)', async () => {
|
||||
jest.spyOn(Course, 'findOne').mockResolvedValue({ subscription: 'premium', status: 'published' });
|
||||
jest.spyOn(mdl_UserTierGrants, 'findOne').mockResolvedValue(null);
|
||||
jest.spyOn(mdl_Product, 'findOne').mockResolvedValue(null);
|
||||
mockActiveTierUnused();
|
||||
|
||||
const result = await canAccessCourse(1, 100);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
test('premium course unlocked by an item-specific grant for THIS exact course', async () => {
|
||||
jest.spyOn(Course, 'findOne').mockResolvedValue({ subscription: 'premium', status: 'published' });
|
||||
jest.spyOn(mdl_UserTierGrants, 'findOne').mockResolvedValue({ item_id: 100 }); // active grant found
|
||||
mockActiveTierUnused();
|
||||
|
||||
const result = await canAccessCourse(1, 100);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
test('premium course still unlocked via a valid individual (a la carte) purchase, unrelated to any tier grant', async () => {
|
||||
jest.spyOn(Course, 'findOne').mockResolvedValue({ subscription: 'premium', status: 'published' });
|
||||
jest.spyOn(mdl_UserTierGrants, 'findOne').mockResolvedValue(null);
|
||||
jest.spyOn(mdl_Product, 'findOne').mockResolvedValue({ id: 55 });
|
||||
jest.spyOn(mdl_CoursePurchase, 'findOne').mockResolvedValue({ id: 1 });
|
||||
mockActiveTierUnused();
|
||||
|
||||
const result = await canAccessCourse(1, 100);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -22,6 +22,10 @@ jest.mock('../../models/courses/courses.mdl', () => ({ Course: {} }));
|
||||
jest.mock('../../services/payment.service', () => ({ captureOrder: jest.fn() }));
|
||||
jest.mock('../../data/notifications.data', () => ({ NOTIFICATION_REGISTRY: {} }));
|
||||
jest.mock('../../models/tiers/tier.associations', () => ({}));
|
||||
// captureOrder now snapshots the plan's bundle into user_tier_grants on every
|
||||
// successful capture (Tier Plans v2 item-specific entitlement) — mocked out
|
||||
// here since these tests only pin the payment-status gating behavior.
|
||||
jest.mock('../../services/tierGrants.service', () => ({ snapshotPlanGrants: jest.fn() }));
|
||||
|
||||
const mdl_UserTiers = require('../../models/tiers/user_tiers.mdl');
|
||||
const mdl_Payments = require('../../models/tiers/payments.mdl');
|
||||
|
||||
Reference in New Issue
Block a user