mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
Implements TDD Task 9: wraps grammY bot.api.getFile/sendPhoto/sendDocument with local attachment staging via AttachmentStore. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
87 lines
3.1 KiB
TypeScript
87 lines
3.1 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach, mock } from 'bun:test'
|
|
import * as fs from 'node:fs/promises'
|
|
import * as path from 'node:path'
|
|
import * as os from 'node:os'
|
|
import { TelegramMediaService } from '../media.js'
|
|
import { AttachmentStore } from '../../common/attachment/attachment-store.js'
|
|
|
|
let tmpRoot: string
|
|
let originalFetch: typeof fetch
|
|
|
|
function makeMockBot() {
|
|
const fetchMock = mock(async (url: string | URL) => {
|
|
const u = typeof url === 'string' ? url : url.toString()
|
|
expect(u).toContain('/file/botFAKE_TOKEN/photos/abc.jpg')
|
|
return new Response(Buffer.from('PHOTODATA'), {
|
|
status: 200,
|
|
headers: { 'content-type': 'image/jpeg' },
|
|
})
|
|
})
|
|
;(globalThis as any).fetch = fetchMock
|
|
return {
|
|
token: 'FAKE_TOKEN',
|
|
api: {
|
|
getFile: mock(async (fileId: string) => ({
|
|
file_id: fileId,
|
|
file_unique_id: 'unique',
|
|
file_path: 'photos/abc.jpg',
|
|
})),
|
|
sendPhoto: mock(async () => ({ message_id: 1 })),
|
|
sendDocument: mock(async () => ({ message_id: 2 })),
|
|
},
|
|
fetchMock,
|
|
}
|
|
}
|
|
|
|
beforeEach(async () => {
|
|
originalFetch = globalThis.fetch
|
|
tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'tg-media-test-'))
|
|
})
|
|
|
|
afterEach(async () => {
|
|
globalThis.fetch = originalFetch
|
|
await fs.rm(tmpRoot, { recursive: true, force: true })
|
|
})
|
|
|
|
describe('TelegramMediaService', () => {
|
|
it('downloadFile fetches the real URL and stores a LocalAttachment', async () => {
|
|
const bot = makeMockBot()
|
|
const store = new AttachmentStore({ root: tmpRoot, retentionMs: 60_000 })
|
|
const svc = new TelegramMediaService(bot as any, store)
|
|
const local = await svc.downloadFile('fid_123', 'sess-1', {
|
|
fileName: 'abc.jpg',
|
|
mimeType: 'image/jpeg',
|
|
})
|
|
expect(local.kind).toBe('image')
|
|
expect(local.name).toBe('abc.jpg')
|
|
expect(local.size).toBe('PHOTODATA'.length)
|
|
expect(local.buffer.toString()).toBe('PHOTODATA')
|
|
const onDisk = await fs.readFile(local.path)
|
|
expect(onDisk.toString()).toBe('PHOTODATA')
|
|
})
|
|
|
|
it('sendPhoto calls bot.api.sendPhoto with InputFile-like payload', async () => {
|
|
const bot = makeMockBot()
|
|
const store = new AttachmentStore({ root: tmpRoot, retentionMs: 60_000 })
|
|
const svc = new TelegramMediaService(bot as any, store)
|
|
await svc.sendPhoto(42, Buffer.from('IMG'), 'caption text')
|
|
expect(bot.api.sendPhoto).toHaveBeenCalledTimes(1)
|
|
const args = (bot.api.sendPhoto as any).mock.calls[0]
|
|
expect(args[0]).toBe(42)
|
|
// grammY InputFile wraps the buffer; just verify it's an object.
|
|
expect(args[1]).toBeDefined()
|
|
expect(args[2]?.caption).toBe('caption text')
|
|
})
|
|
|
|
it('sendDocument calls bot.api.sendDocument', async () => {
|
|
const bot = makeMockBot()
|
|
const store = new AttachmentStore({ root: tmpRoot, retentionMs: 60_000 })
|
|
const svc = new TelegramMediaService(bot as any, store)
|
|
await svc.sendDocument(42, Buffer.from('DOC'), 'spec.pdf')
|
|
expect(bot.api.sendDocument).toHaveBeenCalledTimes(1)
|
|
const args = (bot.api.sendDocument as any).mock.calls[0]
|
|
expect(args[0]).toBe(42)
|
|
expect(args[1]).toBeDefined()
|
|
})
|
|
})
|