Files
TanTan fa9c73363d
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run
SnowLuma v2.4.2 source snapshot
2026-11-13 09:02:00 +08:00

76 lines
2.8 KiB
TypeScript

import type { PacketInfo } from '@snowluma/common/protocol-types';
import type { PushMsg } from '@snowluma/proto-defs/message';
import type { GeneralGrayTipInfo } from '@snowluma/proto-defs/notify';
import { protobuf_encode } from '@snowluma/proton';
import { describe, expect, it } from 'vitest';
import { IdentityService } from '../../src/identity-service';
import { parseMsgPush } from '../../src/msg-push';
const SELF_UIN = 10001;
const FRIEND_A = 20001;
const FRIEND_B = 20002;
const identity = IdentityService.memory(String(SELF_UIN));
function friendPokePacket(peerUin: number, senderUin: number, targetUin: number): PacketInfo {
const sentBySelf = senderUin === SELF_UIN;
const grayTip = protobuf_encode<GeneralGrayTipInfo>({
busiType: 12n,
msgTemplParam: [
{ name: 'uin_str1', value: String(senderUin) },
{ name: 'uin_str2', value: String(targetUin) },
{ name: 'action_str', value: '拍了拍' },
{ name: 'suffix_str', value: '一下' },
],
});
const body = protobuf_encode<PushMsg>({
message: {
responseHead: sentBySelf
? { fromUin: SELF_UIN, toUin: peerUin }
: { fromUin: peerUin, toUin: SELF_UIN },
contentHead: {
msgType: 528,
subType: 290,
timestamp: 1710000000,
},
body: { msgContent: grayTip },
},
});
return {
pid: 1,
uin: String(SELF_UIN),
serviceCmd: 'trpc.msg.olpush.OlPushService.MsgPush',
seqId: 1,
retCode: 0,
fromClient: false,
body,
};
}
describe('parseMsgPush — private poke conversation identity (#285)', () => {
it('preserves the private peer independently of the poke sender and target', () => {
const events = [
...parseMsgPush(friendPokePacket(FRIEND_A, SELF_UIN, SELF_UIN), identity),
...parseMsgPush(friendPokePacket(FRIEND_B, SELF_UIN, SELF_UIN), identity),
...parseMsgPush(friendPokePacket(FRIEND_B, FRIEND_B, SELF_UIN), identity),
];
expect(
events.map((event) => {
const poke = event as unknown as Record<string, unknown>;
return {
kind: poke.kind,
peerUin: poke.peerUin,
senderUin: poke.senderUin,
targetUin: poke.targetUin,
};
}),
).toEqual([
{ kind: 'friend_poke', peerUin: FRIEND_A, senderUin: SELF_UIN, targetUin: SELF_UIN },
{ kind: 'friend_poke', peerUin: FRIEND_B, senderUin: SELF_UIN, targetUin: SELF_UIN },
{ kind: 'friend_poke', peerUin: FRIEND_B, senderUin: FRIEND_B, targetUin: SELF_UIN },
]);
});
});