145 行
5.9 KiB
TypeScript
145 行
5.9 KiB
TypeScript
import { PlatformSubscriptionService } from '../../../src/modules/team/service/platform-subscription';
|
|
import { AdminPlatformSubscriptionController } from '../../../src/modules/team/controller/admin/platform';
|
|
|
|
describe('平台总后台超级管理员 - 会员、续费与订阅服务测试 (TDD)', () => {
|
|
let service: PlatformSubscriptionService;
|
|
|
|
beforeEach(() => {
|
|
service = new PlatformSubscriptionService();
|
|
});
|
|
|
|
describe('1. 平台总览与指标概览', () => {
|
|
it('getOverview 应返回全网会员数、付费会员数、预警会员数及总续费额', async () => {
|
|
const overview = await service.getOverview();
|
|
expect(overview).toBeDefined();
|
|
expect(overview.totalSubscribers).toBeGreaterThan(0);
|
|
expect(overview.activeSubscribers).toBeGreaterThan(0);
|
|
expect(overview.proCount).toBeGreaterThanOrEqual(0);
|
|
expect(overview.enterpriseCount).toBeGreaterThanOrEqual(0);
|
|
expect(overview.totalRenewalRevenue).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe('2. 会员列表管理 (Subscribers)', () => {
|
|
it('getSubscribers 应支持分页查询与全量列表', async () => {
|
|
const res = await service.getSubscribers({ page: 1, size: 10 });
|
|
expect(res.list).toBeDefined();
|
|
expect(Array.isArray(res.list)).toBe(true);
|
|
expect(res.pagination.total).toBeGreaterThan(0);
|
|
expect(res.list[0]).toHaveProperty('tenantName');
|
|
expect(res.list[0]).toHaveProperty('planType');
|
|
expect(res.list[0]).toHaveProperty('cardsLimit');
|
|
expect(res.list[0]).toHaveProperty('seatsLimit');
|
|
});
|
|
|
|
it('getSubscribers 应支持按套餐类型筛选 (pro / enterprise / free)', async () => {
|
|
const proList = await service.getSubscribers({ planType: 'pro' });
|
|
for (const item of proList.list) {
|
|
expect(item.planType).toBe('pro');
|
|
}
|
|
});
|
|
|
|
it('getSubscribers 应支持按状态筛选 (active / trialing / past_due / canceled)', async () => {
|
|
const activeList = await service.getSubscribers({ status: 'active' });
|
|
for (const item of activeList.list) {
|
|
expect(item.status).toBe('active');
|
|
}
|
|
});
|
|
|
|
it('getSubscribers 应支持按关键词搜索企业名称或邮箱', async () => {
|
|
const all = await service.getSubscribers();
|
|
const first = all.list[0];
|
|
const searchRes = await service.getSubscribers({ keyword: first.adminEmail });
|
|
expect(searchRes.list.some(s => s.tenantId === first.tenantId)).toBe(true);
|
|
});
|
|
|
|
it('updateSubscriber 应支持超管修改会员套餐、配额与状态', async () => {
|
|
const updated = await service.updateSubscriber({
|
|
tenantId: 1,
|
|
planType: 'enterprise',
|
|
cardsLimit: 88,
|
|
seatsLimit: 30,
|
|
status: 'active',
|
|
});
|
|
expect(updated.planType).toBe('enterprise');
|
|
expect(updated.cardsLimit).toBe(88);
|
|
expect(updated.seatsLimit).toBe(30);
|
|
});
|
|
|
|
it('updateSubscriber 应支持延长会员有效期 (extendDays)', async () => {
|
|
const before = (await service.getSubscribers({ keyword: '1' })).list.find(s => s.tenantId === 1);
|
|
const updated = await service.updateSubscriber({
|
|
tenantId: 1,
|
|
extendDays: 30,
|
|
});
|
|
expect(updated.expireDate).toBeDefined();
|
|
if (before?.expireDate) {
|
|
expect(new Date(updated.expireDate).getTime()).toBeGreaterThan(new Date(before.expireDate).getTime());
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('3. 续费流水管理与手动代续费 (Renewals)', () => {
|
|
it('getRenewals 应返回全网订单续费流水', async () => {
|
|
const res = await service.getRenewals({ page: 1, size: 10 });
|
|
expect(res.list).toBeDefined();
|
|
expect(Array.isArray(res.list)).toBe(true);
|
|
expect(res.list.length).toBeGreaterThan(0);
|
|
expect(res.list[0]).toHaveProperty('orderNo');
|
|
expect(res.list[0]).toHaveProperty('amount');
|
|
expect(res.list[0]).toHaveProperty('channel');
|
|
});
|
|
|
|
it('manualRenew 应允许超级管理员手动为会员办理续费并生成流水与延期', async () => {
|
|
const renewRes = await service.manualRenew({
|
|
tenantId: 2,
|
|
planType: 'pro',
|
|
billingCycle: 'yearly',
|
|
amount: 588,
|
|
currency: 'USD',
|
|
channel: 'manual_admin',
|
|
note: '总后台超级管理员代续费测试',
|
|
});
|
|
expect(renewRes.success).toBe(true);
|
|
expect(renewRes.orderNo).toMatch(/^ORD-/);
|
|
|
|
// 验证会员列表里的到期时间与套餐已相应更新
|
|
const sub = (await service.getSubscribers({ keyword: '2' })).list.find(s => s.tenantId === 2);
|
|
expect(sub?.planType).toBe('pro');
|
|
});
|
|
});
|
|
|
|
describe('4. SaaS 套餐定价与规格矩阵配置 (Plans)', () => {
|
|
it('getPlans 应返回 Free, Pro, Enterprise 套餐规格', async () => {
|
|
const plans = await service.getPlans();
|
|
expect(plans.length).toBe(3);
|
|
expect(plans.map(p => p.planType)).toEqual(expect.arrayContaining(['free', 'pro', 'enterprise']));
|
|
});
|
|
|
|
it('updatePlan 应支持更新套餐定价与限额', async () => {
|
|
const updated = await service.updatePlan('pro', {
|
|
monthlyPrice: 59,
|
|
yearlyPrice: 599,
|
|
cardsLimit: 15,
|
|
});
|
|
expect(updated.monthlyPrice).toBe(59);
|
|
expect(updated.yearlyPrice).toBe(599);
|
|
expect(updated.cardsLimit).toBe(15);
|
|
});
|
|
});
|
|
|
|
describe('5. 控制器路由与契约完整性', () => {
|
|
it('AdminPlatformSubscriptionController 必须正确导出且声明各总控方法', () => {
|
|
const controller = new AdminPlatformSubscriptionController();
|
|
expect(controller).toBeDefined();
|
|
expect(typeof controller.overview).toBe('function');
|
|
expect(typeof controller.subscribersPage).toBe('function');
|
|
expect(typeof controller.subscribersUpdate).toBe('function');
|
|
expect(typeof controller.renewalsPage).toBe('function');
|
|
expect(typeof controller.manualRenew).toBe('function');
|
|
expect(typeof controller.plansList).toBe('function');
|
|
expect(typeof controller.plansUpdate).toBe('function');
|
|
});
|
|
});
|
|
});
|