Files
SnowLuma/packages/onebot/tests/media-indexer.test.ts
T
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

134 lines
4.8 KiB
TypeScript

import { describe, it, expect, vi } from 'vitest';
import { MediaIndexer } from '../src/media-indexer';
import type { MessageElement } from '@snowluma/protocol/events';
function makeMediaStore() {
return {
rememberImage: vi.fn(),
rememberRecord: vi.fn(),
rememberVideo: vi.fn(),
};
}
describe('MediaIndexer', () => {
it('image: maps element fields into rememberImage with file fallback to fileId', async () => {
const store = makeMediaStore();
const indexer = new MediaIndexer(store as any);
const element: MessageElement = {
type: 'image',
fileId: 'img-fid',
fileSize: 1024,
subType: 1,
summary: '[image]',
imageUrl: 'http://orig',
md5Hex: 'abcd',
sha1Hex: 'efgh',
width: 800,
height: 600,
picFormat: 1000,
};
await indexer.remember('image', element, { url: 'http://x', file: '' }, true, 99999);
expect(store.rememberImage).toHaveBeenCalledOnce();
const arg = store.rememberImage.mock.calls[0]![0];
expect(arg).toMatchObject({
file: 'img-fid', // data.file was '', fell back to element.fileId
url: 'http://x',
fileSize: 1024,
subType: 1,
summary: '[image]',
imageUrl: 'http://orig',
isGroup: true,
sessionId: 99999,
md5Hex: 'abcd',
sha1Hex: 'efgh',
width: 800,
height: 600,
picFormat: 1000,
});
});
it('record: maps element fields into rememberRecord with file fallback chain', async () => {
const store = makeMediaStore();
const indexer = new MediaIndexer(store as any);
const element: MessageElement = {
type: 'record',
fileId: 'rec-fid',
fileName: 'voice.amr',
fileSize: 2048,
duration: 5,
fileHash: 'h',
mediaNode: { fileUuid: 'uuid' },
md5Hex: 'm',
sha1Hex: 's',
voiceFormat: 1,
};
await indexer.remember('record', element, { url: 'http://r', file: '' }, false, 12345);
const arg = store.rememberRecord.mock.calls[0]![0];
expect(arg.file).toBe('voice.amr'); // data.file '' → element.fileName
expect(arg.fileId).toBe('rec-fid');
expect(arg.duration).toBe(5);
expect(arg.isGroup).toBe(false);
expect(arg.sessionId).toBe(12345);
expect(arg.voiceFormat).toBe(1);
});
it('video: maps element fields into rememberVideo', async () => {
const store = makeMediaStore();
const indexer = new MediaIndexer(store as any);
const element: MessageElement = {
type: 'video',
fileId: 'vid-fid',
fileName: 'clip.mp4',
fileSize: 99999,
duration: 30,
width: 1920,
height: 1080,
videoFormat: 2,
};
await indexer.remember(
'video',
element,
{ url: 'http://v', file: 'override.mp4' },
true,
11111,
);
const arg = store.rememberVideo.mock.calls[0]![0];
expect(arg.file).toBe('override.mp4'); // data.file used when non-empty
expect(arg.fileId).toBe('vid-fid');
expect(arg.duration).toBe(30);
expect(arg.width).toBe(1920);
expect(arg.videoFormat).toBe(2);
});
it('falls back to element.fileId when data.file AND element.fileName are missing (record)', async () => {
const store = makeMediaStore();
const indexer = new MediaIndexer(store as any);
const element: MessageElement = { type: 'record', fileId: 'only-fid' };
await indexer.remember('record', element, { url: '', file: '' }, false, 1);
expect(store.rememberRecord.mock.calls[0]![0].file).toBe('only-fid');
});
it('defaults missing numeric fields to 0 / missing strings to ""', async () => {
const store = makeMediaStore();
const indexer = new MediaIndexer(store as any);
await indexer.remember('image', { type: 'image' }, { url: '', file: '' }, false, 0);
const arg = store.rememberImage.mock.calls[0]![0];
expect(arg.fileSize).toBe(0);
expect(arg.subType).toBe(0);
expect(arg.summary).toBe('');
expect(arg.imageUrl).toBe('');
});
it('only the matching rememberX is called', async () => {
const store = makeMediaStore();
const indexer = new MediaIndexer(store as any);
await indexer.remember('image', { type: 'image' }, { url: '', file: 'a' }, true, 1);
expect(store.rememberImage).toHaveBeenCalledOnce();
expect(store.rememberRecord).not.toHaveBeenCalled();
expect(store.rememberVideo).not.toHaveBeenCalled();
});
});