kt-template-online-api/test/modules/qqbot/message-push/qqbot-account-message-push.service.spec.ts

164 lines
5.2 KiB
TypeScript

import { QqbotAccountMessagePushService } from '../../../../src/modules/qqbot/core/application/message-push/qqbot-account-message-push.service';
import { SystemMessageContractError } from '../../../../src/modules/qqbot/core/contract/message-push/qqbot-message-push.types';
import { QqbotMessagePublishBinding } from '../../../../src/modules/qqbot/core/infrastructure/persistence/message-push/qqbot-message-publish-binding.entity';
import { QqbotMessagePublishTarget } from '../../../../src/modules/qqbot/core/infrastructure/persistence/message-push/qqbot-message-publish-target.entity';
describe('QqbotAccountMessagePushService', () => {
it('normalizes targets without number coercion and rejects invalid manual values', () => {
const service = new QqbotAccountMessagePushService(
{} as never,
{} as never,
{} as never,
{} as never,
{} as never,
{} as never,
{} as never,
{} as never,
{} as never,
);
expect(
(service as any).normalizeTargets([
{
targetId: ' 20000000000000001 ',
targetName: ' 群 ',
targetType: 'group',
},
{ targetId: '20000000000000001', targetType: 'private' },
{
targetId: '20000000000000001',
targetName: '覆盖',
targetType: 'group',
},
]),
).toEqual([
{
targetId: '20000000000000001',
targetName: '覆盖',
targetType: 'group',
},
{
targetId: '20000000000000001',
targetName: null,
targetType: 'private',
},
]);
expect(() =>
(service as any).normalizeTargets([
{ targetId: '00001', targetType: 'group' },
]),
).toThrow(new SystemMessageContractError('invalid_target_id'));
expect(() =>
(service as any).normalizeTargets([
{ targetId: '10001', targetType: 'channel' },
]),
).toThrow(new SystemMessageContractError('invalid_target_type'));
});
it('holds subscription then template gates through multi-target persistence without coercing IDs', async () => {
const events: string[] = [];
const targetRows: any[] = [];
const subscription = {
enabled: true,
id: '2041700000000000001',
isDeleted: false,
name: '订阅',
sourceConfig: {},
sourceKey: 'network.stun.mapping-port-changed',
};
const template = {
content: '正文',
enabled: true,
id: '2041700000000000002',
isDeleted: false,
name: '模板',
sourceKey: subscription.sourceKey,
};
const bindingStore = {
create: (value: any) => ({
...value,
createTime: '2026-07-24',
id: '2041700000000000003',
updateTime: '2026-07-24',
}),
findOne: jest.fn().mockResolvedValue(null),
save: async (value: any) => {
events.push('binding');
return value;
},
};
const targetStore = {
create: (value: any) => ({
...value,
createTime: '2026-07-24',
id: `target-${targetRows.length + 1}`,
updateTime: '2026-07-24',
}),
find: jest.fn().mockResolvedValue([]),
save: async (values: any[]) => {
events.push('targets');
targetRows.splice(0, targetRows.length, ...values);
return values;
},
};
const manager = {
getRepository: (entity: unknown) => {
if (entity === QqbotMessagePublishBinding) return bindingStore;
if (entity === QqbotMessagePublishTarget) return targetStore;
throw new Error('unexpected repository');
},
};
const service = new QqbotAccountMessagePushService(
{
manager: { transaction: async (callback: any) => callback(manager) },
} as never,
{ find: async () => targetRows } as never,
{ findOne: async () => subscription } as never,
{ findOne: async () => template } as never,
{
findBySelfId: async () => ({
id: '2041700000000000000',
selfId: '10000000000000001',
}),
} as never,
{
requireAvailableForBinding: async () => {
events.push('subscription');
return subscription;
},
} as never,
{
requireAvailableForBinding: async () => {
events.push('template');
return template;
},
} as never,
{
get: () => ({
definition: { displayName: 'STUN 映射', variables: [] },
inspectSubscription: async () => ({ valid: true }),
}),
} as never,
{ validate: jest.fn() } as never,
);
await expect(
service.createBinding('10000000000000001', {
enabled: true,
subscriptionId: '2041700000000000001',
templateId: '2041700000000000002',
targets: [
{ targetId: '20000000000000001', targetType: 'group' },
{ targetId: '30000000000000001', targetType: 'private' },
],
}),
).resolves.toMatchObject({
id: '2041700000000000003',
targets: [
{ targetId: '20000000000000001', targetType: 'group' },
{ targetId: '30000000000000001', targetType: 'private' },
],
});
expect(events).toEqual(['subscription', 'template', 'binding', 'targets']);
});
});