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

70 lines
2.6 KiB
TypeScript

import { describe, it, expect, vi } from 'vitest';
import type { MessageElement } from '@snowluma/protocol/events';
import { getImageInfo } from '../src/modules/media-actions';
import type { CachedImage, MediaStore } from '../src/media-store';
const RAW = 'https://multimedia.nt.qq.com.cn/download?appid=1407&fileid=ABC';
function fakeStore(image: CachedImage | null): MediaStore {
return { findImage: () => image } as unknown as MediaStore;
}
function cachedImage(overrides: Partial<CachedImage> = {}): CachedImage {
return {
file: 'ABC.jpg',
url: `${RAW}&rkey=STALE`, // signed when the message arrived; now expired
fileSize: 100,
fileName: 'ABC.jpg',
subType: 0,
summary: '',
isGroup: true,
sessionId: 123,
imageUrl: RAW, // raw, unsigned — the basis for re-signing
...overrides,
};
}
describe('getImageInfo — rkey re-signing at lookup time', () => {
it('re-signs from the raw imageUrl via the resolver', async () => {
const resolver = vi.fn(async (el: MessageElement) => `${el.imageUrl}&rkey=FRESH`);
const info = await getImageInfo(fakeStore(cachedImage()), 'ABC.jpg', resolver);
expect(info?.url).toBe(`${RAW}&rkey=FRESH`);
expect(info?.file).toBe(`${RAW}&rkey=FRESH`);
expect(resolver).toHaveBeenCalledWith(
expect.objectContaining({ type: 'image', imageUrl: RAW }),
true, // isGroup carried through
);
});
it('returns the stored URL when no resolver is wired', async () => {
const info = await getImageInfo(fakeStore(cachedImage()), 'ABC.jpg');
expect(info?.url).toBe(`${RAW}&rkey=STALE`);
});
it('falls back to the stored URL when the resolver throws', async () => {
const resolver = vi.fn(async () => {
throw new Error('rkey fetch failed');
});
const info = await getImageInfo(fakeStore(cachedImage()), 'ABC.jpg', resolver);
expect(info?.url).toBe(`${RAW}&rkey=STALE`);
});
it('skips re-signing when no raw imageUrl is stored', async () => {
const resolver = vi.fn(async () => 'should-not-be-used');
const info = await getImageInfo(
fakeStore(cachedImage({ imageUrl: '' })),
'ABC.jpg',
resolver,
);
expect(resolver).not.toHaveBeenCalled();
expect(info?.url).toBe(`${RAW}&rkey=STALE`);
});
it('returns null when the image is not cached', async () => {
const info = await getImageInfo(fakeStore(null), 'missing.jpg');
expect(info).toBeNull();
});
});