test(message): pin response mapping across batch boundaries (#2255)

This commit is contained in:
Hampus authored and GitHub committed 2026-08-31 16:24:33 +02:00
1 parent f0612ee860
commit 0eef611b6d
1 file changed
+32 -6
@@ -32,13 +32,13 @@ class FakeConnectionManager implements INatsConnectionManager {
this.payloads.push(payload); this.payloads.push(payload);
this.timeouts.push(options?.timeout); this.timeouts.push(options?.timeout);
if (payload.op === 'BuildResponses') { if (payload.op === 'BuildResponses') {
const messages = (payload.messages as Array<{message_id: string}>).filter( const messages = (payload.messages as Array<{message_id: string; channel_id: string}>).filter(
(message) => !this.orphanedMessageIds.has(message.message_id), (message) => !this.orphanedMessageIds.has(message.message_id),
); );
return { return {
data: encoder.encode( data: encoder.encode(
JSON.stringify({ JSON.stringify({
FoundApiMany: messages.map((message) => fakeMessageResponse(message.message_id)), FoundApiMany: messages.map((message) => fakeMessageResponse(message.message_id, message.channel_id)),
}), }),
), ),
}; };
@@ -51,10 +51,10 @@ class FakeConnectionManager implements INatsConnectionManager {
} }
} }
function fakeMessageResponse(messageId: string): Record<string, unknown> { function fakeMessageResponse(messageId: string, channelId: string = '1'): Record<string, unknown> {
return { return {
id: messageId, id: messageId,
channel_id: '1', channel_id: channelId,
author: {id: '3', username: 'author', discriminator: '0001', avatar: null, flags: 0}, author: {id: '3', username: 'author', discriminator: '0001', avatar: null, flags: 0},
type: MessageTypes.DEFAULT, type: MessageTypes.DEFAULT,
flags: 0, flags: 0,
@@ -114,8 +114,8 @@ async function measureSerializedMessageBytes(): Promise<number> {
return Buffer.byteLength(JSON.stringify(messages[0])); return Buffer.byteLength(JSON.stringify(messages[0]));
} }
function makeSizedMessage(index: number, totalBytes: number, baseBytes: number): Message { function makeSizedMessage(index: number, totalBytes: number, baseBytes: number, channelId: bigint = 1n): Message {
return makeMessage(BASE_MESSAGE_ID + BigInt(index), 'a'.repeat(totalBytes - baseBytes)); return makeMessage(BASE_MESSAGE_ID + BigInt(index), 'a'.repeat(totalBytes - baseBytes), channelId);
} }
function messageId(index: number): string { function messageId(index: number): string {
@@ -267,6 +267,32 @@ describe('MessageResponseDataService', () => {
expect(responses.map((response) => response.id)).toEqual([messageId(0), messageId(1), messageId(3)]); expect(responses.map((response) => response.id)).toEqual([messageId(0), messageId(1), messageId(3)]);
}); });
it('keeps other guilds aligned when an earlier batch drops a message', async () => {
const baseBytes = await measureSerializedMessageBytes();
const connectionManager = new FakeConnectionManager();
connectionManager.orphanedMessageIds.add(messageId(0));
const service = new MessageResponseDataService(connectionManager);
const messages = [
makeSizedMessage(0, MESSAGE_BUILD_BATCH_MAX_BYTES / 2, baseBytes, 10n),
makeMessage(BASE_MESSAGE_ID + 1n, '', 20n),
makeSizedMessage(2, MESSAGE_BUILD_BATCH_MAX_BYTES / 2 + 1, baseBytes, 10n),
makeSizedMessage(3, baseBytes, baseBytes, 10n),
];
const responses = await service.buildMessagesForChannels({
userId: VIEWER_ID,
messages,
channelById: new Map([
['10', {guildId: createGuildID(100n)}],
['20', {guildId: createGuildID(200n)}],
]),
});
expect(batchSizes(connectionManager).sort()).toEqual([1, 1, 2]);
expect(responses.map((response) => response.id)).toEqual([messageId(1), messageId(2), messageId(3)]);
expect(responses.map((response) => response.channel_id)).toEqual(['20', '10', '10']);
});
it('keeps a full page of ordinary pins in a single request', async () => { it('keeps a full page of ordinary pins in a single request', async () => {
const connectionManager = new FakeConnectionManager(); const connectionManager = new FakeConnectionManager();
const service = new MessageResponseDataService(connectionManager); const service = new MessageResponseDataService(connectionManager);