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
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:
commit
fa9c73363d
1367 files changed
+355735
No files matched your search
@@ -0,0 +1,133 @@
|
||||
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();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user