flnxi-Wu/lib/__tests__/check-limits.test.ts
2026-06-03 18:41:52 +08:00

217 lines
6.6 KiB
TypeScript

/**
* 许可证限制检查工具测试。
*
* 当前商业化口径:
* - 免费版人数/素材数限制由基础镜像读取本地签名许可证执行。
* - 付费能力统一要求 paid-core 授权模块运行并放行。
*/
import {
canCreateUser,
canUploadMaterial,
canUseApiAccess,
canUseCustomTemplates,
canUseDepartmentIsolation,
canUseIntranetPenetration,
canUseSystemSettings,
} from '../license/check-limits';
jest.mock('../license/license-service', () => ({
checkLimit: jest.fn(),
getLicenseType: jest.fn(),
isFeatureEnabled: jest.fn(),
}));
jest.mock('../license/premium-module-service', () => ({
authorizePremiumModuleAction: jest.fn(),
PREMIUM_MODULE_IDS: {
PAID_CORE: 'paid-core',
},
}));
import { checkLimit, getLicenseType, isFeatureEnabled } from '../license/license-service';
import { authorizePremiumModuleAction } from '../license/premium-module-service';
const mockCheckLimit = checkLimit as jest.MockedFunction<typeof checkLimit>;
const mockGetLicenseType = getLicenseType as jest.MockedFunction<typeof getLicenseType>;
const mockIsFeatureEnabled = isFeatureEnabled as jest.MockedFunction<typeof isFeatureEnabled>;
const mockAuthorizePremiumModuleAction =
authorizePremiumModuleAction as jest.MockedFunction<typeof authorizePremiumModuleAction>;
describe('基础镜像限额检查', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('未达到用户限制时允许创建用户', async () => {
mockCheckLimit.mockResolvedValue({
allowed: true,
current: 5,
max: 10,
});
await expect(canCreateUser()).resolves.toEqual({
allowed: true,
current: 5,
max: 10,
});
expect(mockCheckLimit).toHaveBeenCalledWith('users');
});
it('FREE 达到用户限制时返回授权处理提示', async () => {
mockCheckLimit.mockResolvedValue({
allowed: false,
current: 10,
max: 10,
});
mockGetLicenseType.mockResolvedValue('FREE');
const result = await canCreateUser();
expect(result.allowed).toBe(false);
expect(result.message).toContain('当前许可证');
expect(result.message).toContain('10');
expect(result.message).toContain('联系管理员');
});
it('未达到素材限制时允许上传素材', async () => {
mockCheckLimit.mockResolvedValue({
allowed: true,
current: 50,
max: 100,
});
await expect(canUploadMaterial()).resolves.toEqual({
allowed: true,
current: 50,
max: 100,
});
expect(mockCheckLimit).toHaveBeenCalledWith('materials');
});
it('FREE 达到素材限制时返回授权处理提示', async () => {
mockCheckLimit.mockResolvedValue({
allowed: false,
current: 100,
max: 100,
});
mockGetLicenseType.mockResolvedValue('FREE');
const result = await canUploadMaterial();
expect(result.allowed).toBe(false);
expect(result.message).toContain('当前许可证');
expect(result.message).toContain('素材');
expect(result.message).toContain('联系管理员');
});
it('本地许可证限制已有错误信息时直接返回', async () => {
mockCheckLimit.mockResolvedValue({
allowed: false,
current: 0,
max: 0,
message: '许可证不可用',
} as any);
await expect(canCreateUser()).resolves.toEqual({
allowed: false,
current: 0,
max: 0,
message: '许可证不可用',
});
expect(mockGetLicenseType).not.toHaveBeenCalled();
});
});
describe('paid-core 付费功能门禁', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('自定义模板必须同时满足许可证功能开关和 paid-core 授权', async () => {
mockIsFeatureEnabled.mockResolvedValue(true);
mockAuthorizePremiumModuleAction.mockResolvedValue({
available: true,
moduleId: 'paid-core',
action: 'customTemplates:use',
status: 'running',
});
await expect(canUseCustomTemplates()).resolves.toBe(true);
expect(mockIsFeatureEnabled).toHaveBeenCalledWith('customTemplates');
expect(mockAuthorizePremiumModuleAction).toHaveBeenCalledWith('paid-core', 'customTemplates:use');
});
it('功能开关关闭时不访问 paid-core', async () => {
mockIsFeatureEnabled.mockResolvedValue(false);
await expect(canUseCustomTemplates()).resolves.toBe(false);
expect(mockAuthorizePremiumModuleAction).not.toHaveBeenCalled();
});
it('部门隔离必须走 paid-core 授权', async () => {
mockIsFeatureEnabled.mockResolvedValue(true);
mockAuthorizePremiumModuleAction.mockResolvedValue({
available: true,
moduleId: 'paid-core',
action: 'departmentIsolation:use',
status: 'running',
});
await expect(canUseDepartmentIsolation()).resolves.toBe(true);
expect(mockAuthorizePremiumModuleAction).toHaveBeenCalledWith('paid-core', 'departmentIsolation:use');
});
it('内网穿透必须走 paid-core 授权', async () => {
mockIsFeatureEnabled.mockResolvedValue(true);
mockAuthorizePremiumModuleAction.mockResolvedValue({
available: true,
moduleId: 'paid-core',
action: 'intranetPenetration:use',
status: 'running',
});
await expect(canUseIntranetPenetration()).resolves.toBe(true);
expect(mockAuthorizePremiumModuleAction).toHaveBeenCalledWith('paid-core', 'intranetPenetration:use');
});
it('系统设置必须走 paid-core 授权', async () => {
mockIsFeatureEnabled.mockResolvedValue(true);
mockAuthorizePremiumModuleAction.mockResolvedValue({
available: true,
moduleId: 'paid-core',
action: 'systemSettings:use',
status: 'running',
});
await expect(canUseSystemSettings()).resolves.toBe(true);
expect(mockAuthorizePremiumModuleAction).toHaveBeenCalledWith('paid-core', 'systemSettings:use');
});
it('paid-core 拒绝时付费能力不可用', async () => {
mockIsFeatureEnabled.mockResolvedValue(true);
mockAuthorizePremiumModuleAction.mockResolvedValue({
available: false,
moduleId: 'paid-core',
action: 'customTemplates:use',
status: 'missing',
});
await expect(canUseCustomTemplates()).resolves.toBe(false);
});
it('API 访问必须走 paid-core 授权', async () => {
mockIsFeatureEnabled.mockResolvedValue(true);
mockAuthorizePremiumModuleAction.mockResolvedValue({
available: true,
moduleId: 'paid-core',
action: 'apiAccess:use',
status: 'running',
});
await expect(canUseApiAccess()).resolves.toBe(true);
expect(mockIsFeatureEnabled).toHaveBeenCalledWith('apiAccess');
expect(mockAuthorizePremiumModuleAction).toHaveBeenCalledWith('paid-core', 'apiAccess:use');
});
});