46 lines
3.4 KiB
JavaScript
46 lines
3.4 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { buildApp } from '../dist/app.js';
|
|
import { signAccessToken } from '../dist/auth/jwt.js';
|
|
|
|
const secret = 'test-only-franchise-management-secret-32';
|
|
const token = signAccessToken({ sub: '21', sid: '5c4d3af8-c63c-4edb-bf95-b84127bb3f6e', tid: '7', aid: '9', rv: 1 }, secret, 900);
|
|
let submitted;
|
|
let listInput;
|
|
let assignment;
|
|
let followUp;
|
|
const repository = {
|
|
async submitApplication(input) { submitted = input; return { applicationId: '101', applicationNo: 'FR101', idempotent: false }; },
|
|
async listApplications(input) { listInput = input; return { items: [], total: 0, page: input.page, pageSize: input.pageSize }; },
|
|
async getApplication(tenantId, id) { return { application: { id, tenantId }, followUps: [] }; },
|
|
async assignApplication(_actor, tenantId, id, assigneeUserId) { assignment = { tenantId, id, assigneeUserId }; return { applicationId: id, assigneeUserId }; },
|
|
async addFollowUp(_actor, tenantId, id, input) { followUp = { tenantId, id, input }; return { applicationId: id, followUpId: '301', status: input.status || 'NEW' }; }
|
|
};
|
|
const app = await buildApp({ franchise: {
|
|
repository,
|
|
platformConfig: { async resolveBootstrap(appId, tenantId) { return appId === 'wx-franchise' ? { tenantId: tenantId || '7' } : null; } },
|
|
authRepository: { async validateSession() { return { id: '5c4d3af8-c63c-4edb-bf95-b84127bb3f6e', tenantId: '7', platformAppId: '9', expiresAt: new Date(Date.now() + 60000), user: { id: '21', tenantId: '7', userType: 'STAFF', status: 'ACTIVE', roleVersion: 1, nickname: '', avatarUrl: '', phone: '' } }; } },
|
|
accessControl: { async getAccessProfile() { return { roles: ['TENANT_ADMIN'], capabilities: ['tenant.manage'], storeIds: [] }; } },
|
|
jwtSecret: secret
|
|
} });
|
|
|
|
const created = await app.inject({ method: 'POST', url: '/app-api/franchise-applications', headers: { 'x-wechat-appid': 'wx-franchise' }, payload: { city: '上海市', contactName: '张先生', contactPhone: '13800138000', message: '计划开店', clientRequestId: 'franchise-request-001' } });
|
|
assert.equal(created.statusCode, 201);
|
|
assert.equal(submitted.tenantId, '7');
|
|
assert.equal(submitted.contactPhone, '13800138000');
|
|
assert.equal('contactPhone' in (submitted.audit || {}), false);
|
|
|
|
const auth = { authorization: `Bearer ${token}` };
|
|
const listed = await app.inject({ method: 'GET', url: '/admin-api/franchise-applications?status=NEW&page=2&pageSize=10', headers: auth });
|
|
assert.equal(listed.statusCode, 200);
|
|
assert.deepEqual({ tenantId: listInput.tenantId, status: listInput.status, page: listInput.page }, { tenantId: '7', status: 'NEW', page: 2 });
|
|
const crossTenant = await app.inject({ method: 'GET', url: '/admin-api/franchise-applications?tenantId=8', headers: auth });
|
|
assert.equal(crossTenant.statusCode, 403);
|
|
const assigned = await app.inject({ method: 'PATCH', url: '/admin-api/franchise-applications/101/assignee', headers: auth, payload: { assigneeUserId: '22' } });
|
|
assert.equal(assigned.statusCode, 200);
|
|
assert.deepEqual(assignment, { tenantId: '7', id: '101', assigneeUserId: '22' });
|
|
const followed = await app.inject({ method: 'POST', url: '/admin-api/franchise-applications/101/follow-ups', headers: auth, payload: { followUpType: 'CALL', note: '已电话沟通', status: 'CONTACTED' } });
|
|
assert.equal(followed.statusCode, 201);
|
|
assert.equal(followUp.input.status, 'CONTACTED');
|
|
await app.close();
|
|
console.log('PASS: M08-D franchise submission, tenant scope, assignment and follow-up routes are present.');
|