SnowLuma v2.4.2 source snapshot
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

This commit is contained in:
TanTan committed 2026-11-13 09:02:00 +08:00
commit fa9c73363d
1367 files changed
+355735

No files matched your search

@@ -0,0 +1,288 @@
import fs from 'fs';
import os from 'os';
import path from 'path';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { convertFriendMessage } from '../src/event-converter/to-message';
import {
hashMessageIdInt32,
PRIVATE_NT_MESSAGE_EVENT,
PRIVATE_SENT_MESSAGE_EVENT,
} from '../src/message-id';
import { MessageStore } from '../src/message-store';
import { createMessageIdResolver as productionResolver } from '../src/message-id-resolver';
import type { ConverterContext } from '../src/event-converter';
import type { FriendMessage } from '@snowluma/protocol/events';
const SELF_ID = 3961840894;
const PEER_ID = 2705892349;
describe('private reply id matches send receipt (#417, #433)', () => {
let dir: string;
let store: MessageStore;
beforeEach(async () => {
dir = fs.mkdtempSync(path.join(os.tmpdir(), 'sl-reply-id-'));
store = new MessageStore(path.join(dir, 'messages.db'));
await store.initialization;
});
afterEach(async () => {
await store.close();
fs.rmSync(dir, { recursive: true, force: true });
});
it('matches quoted text instead of a later voice message in the same second (#502)', async () => {
const sentAt = 1_790_000_000;
for (const [id, message] of [
[101, [{ type: 'text', data: { text: 'the quoted text' } }]],
[102, [{ type: 'record', data: { file: 'voice.amr' } }]],
] as const) {
await store.storeMeta(id, {
isGroup: false,
targetId: PEER_ID,
sequence: id,
sequenceAuthoritative: true,
eventName: PRIVATE_NT_MESSAGE_EVENT,
clientSequence: id + 1000,
privateDirection: 'outgoing',
random: id,
timestamp: sentAt,
});
await store.storeEvent(id, false, PEER_ID, id, PRIVATE_NT_MESSAGE_EVENT, {
time: sentAt,
post_type: 'message_sent',
message_type: 'private',
sub_type: 'friend',
message: JSON.parse(JSON.stringify(message)),
});
}
await store.close();
store = new MessageStore(path.join(dir, 'messages.db'));
await store.initialization;
const ctx: ConverterContext = {
selfId: SELF_ID,
imageUrlResolver: null,
mediaUrlResolver: null,
mediaSegmentSink: null,
messageIdResolver: await productionResolver(store),
};
const event: FriendMessage = {
kind: 'friend_message',
time: sentAt + 2,
selfUin: SELF_ID,
senderUin: PEER_ID,
peerUin: PEER_ID,
senderUid: 'u_peer',
senderNick: 'peer',
msgSeq: 2773,
ntMsgSeq: 103,
clientSeq: 2773,
sequenceAuthoritative: true,
msgId: 2,
elements: [
{
type: 'reply',
replySeq: 9999,
replySenderUin: SELF_ID,
replyTime: sentAt,
replyElements: [{ type: 'text', text: 'the quoted text' }],
},
],
};
const json = await convertFriendMessage(ctx, event);
expect(json.message).toEqual([{ type: 'reply', data: { id: '101' } }]);
});
it.each([
{
name: '#433',
ntSeq: 682,
localClientSeq: 201_616_628,
quoteSeq: 27_892,
sentAt: 1_788_102_428,
sendId: -12_721_351,
},
{
name: '#417',
ntSeq: 655,
localClientSeq: 509_147_526,
quoteSeq: 63_878,
sentAt: 1_787_409_444,
sendId: 866_508_396,
},
])(
'$name resolves a quote of a bot-sent private message to the send receipt id',
async (fixture) => {
const sendId = hashMessageIdInt32(fixture.ntSeq, PEER_ID, PRIVATE_NT_MESSAGE_EVENT);
expect(sendId).toBe(fixture.sendId);
expect(sendId).not.toBe(
hashMessageIdInt32(fixture.quoteSeq, PEER_ID, PRIVATE_SENT_MESSAGE_EVENT),
);
await store.storeMeta(sendId, {
isGroup: false,
targetId: PEER_ID,
sequence: fixture.ntSeq,
sequenceAuthoritative: true,
eventName: PRIVATE_NT_MESSAGE_EVENT,
clientSequence: fixture.localClientSeq,
privateDirection: 'outgoing',
random: 1,
timestamp: fixture.sentAt,
});
const ctx: ConverterContext = {
selfId: SELF_ID,
imageUrlResolver: null,
mediaUrlResolver: null,
mediaSegmentSink: null,
messageIdResolver: await productionResolver(store),
};
const event: FriendMessage = {
kind: 'friend_message',
time: fixture.sentAt + 2,
selfUin: SELF_ID,
senderUin: PEER_ID,
peerUin: PEER_ID,
senderUid: 'u_peer',
senderNick: 'peer',
msgSeq: 2773,
ntMsgSeq: fixture.ntSeq + 1,
clientSeq: 2773,
sequenceAuthoritative: true,
msgId: 2,
elements: [
{
type: 'reply',
replySeq: fixture.quoteSeq,
replySenderUin: SELF_ID,
replyTime: fixture.sentAt,
},
{ type: 'text', text: '这是对bot消息的回复消息' },
],
};
const json = await convertFriendMessage(ctx, event);
const reply = (json.message as Array<{ type: string; data: { id: string } }>)[0];
expect(reply).toEqual({ type: 'reply', data: { id: String(sendId) } });
},
);
it('resolves a bot quote when the quote time drifts from the send receipt (#465)', async () => {
const ntSeq = 6008;
const localClientSeq = 567_154_552;
const quoteSeq = 6008;
const sentAt = 1_789_720_450;
const quoteTime = sentAt + 2;
const sendId = hashMessageIdInt32(ntSeq, PEER_ID, PRIVATE_NT_MESSAGE_EVENT);
expect(sendId).not.toBe(hashMessageIdInt32(quoteSeq, PEER_ID, PRIVATE_SENT_MESSAGE_EVENT));
await store.storeMeta(sendId, {
isGroup: false,
targetId: PEER_ID,
sequence: ntSeq,
sequenceAuthoritative: true,
eventName: PRIVATE_NT_MESSAGE_EVENT,
clientSequence: localClientSeq,
privateDirection: 'outgoing',
random: 1,
timestamp: sentAt,
});
const ctx: ConverterContext = {
selfId: SELF_ID,
imageUrlResolver: null,
mediaUrlResolver: null,
mediaSegmentSink: null,
messageIdResolver: await productionResolver(store),
};
const event: FriendMessage = {
kind: 'friend_message',
time: quoteTime + 1,
selfUin: SELF_ID,
senderUin: PEER_ID,
peerUin: PEER_ID,
senderUid: 'u_peer',
senderNick: 'peer',
msgSeq: 6010,
ntMsgSeq: ntSeq + 1,
clientSeq: 6010,
sequenceAuthoritative: true,
msgId: 2,
elements: [
{
type: 'reply',
replySeq: quoteSeq,
replySenderUin: SELF_ID,
replyTime: quoteTime,
},
{ type: 'text', text: '111' },
],
};
const json = await convertFriendMessage(ctx, event);
const reply = (json.message as Array<{ type: string; data: { id: string } }>)[0];
expect(reply).toEqual({ type: 'reply', data: { id: String(sendId) } });
});
it('resolves a bot quote by nearby send time when the quote sequence is unrelated', async () => {
const ntSeq = 682;
const localClientSeq = 201_616_628;
const quoteSeq = 27_892;
const sentAt = 1_788_102_428;
const quoteTime = sentAt + 2;
const sendId = hashMessageIdInt32(ntSeq, PEER_ID, PRIVATE_NT_MESSAGE_EVENT);
await store.storeMeta(sendId, {
isGroup: false,
targetId: PEER_ID,
sequence: ntSeq,
sequenceAuthoritative: true,
eventName: PRIVATE_NT_MESSAGE_EVENT,
clientSequence: localClientSeq,
privateDirection: 'outgoing',
random: 1,
timestamp: sentAt,
});
const ctx: ConverterContext = {
selfId: SELF_ID,
imageUrlResolver: null,
mediaUrlResolver: null,
mediaSegmentSink: null,
messageIdResolver: await productionResolver(store),
};
const event: FriendMessage = {
kind: 'friend_message',
time: quoteTime + 1,
selfUin: SELF_ID,
senderUin: PEER_ID,
peerUin: PEER_ID,
senderUid: 'u_peer',
senderNick: 'peer',
msgSeq: 2773,
ntMsgSeq: ntSeq + 1,
clientSeq: 2773,
sequenceAuthoritative: true,
msgId: 2,
elements: [
{
type: 'reply',
replySeq: quoteSeq,
replySenderUin: SELF_ID,
replyTime: quoteTime,
},
{ type: 'text', text: '这是对bot消息的回复消息' },
],
};
const json = await convertFriendMessage(ctx, event);
const reply = (json.message as Array<{ type: string; data: { id: string } }>)[0];
expect(reply).toEqual({ type: 'reply', data: { id: String(sendId) } });
});
});