217 lines
6.6 KiB
TypeScript
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');
|
|
});
|
|
});
|