import { describe, expect, it, vi } from 'vitest' import { publishToutiaoArticle, type ToutiaoPublishTransport, } from '../../../../../packages/publisher-platforms/src/toutiao' function createTransport( overrides: Partial = {}, ): ToutiaoPublishTransport & { submitCalls: URLSearchParams[] } { const submitCalls: URLSearchParams[] = [] const transport: ToutiaoPublishTransport & { submitCalls: URLSearchParams[] } = { submitCalls, async fetchJson(input, init) { if (input.includes('/media/get_media_info')) { return { data: { user: { id_str: 'uid-1', screen_name: '头条号测试账号', }, media: {}, }, } as never } if (input.includes('/spice/image')) { return { data: { image_url: 'https://p3-sign.toutiaoimg.com/tos-cn-i-body/image.png', image_uri: 'tos-cn-i-body/image.png', image_width: 640, image_height: 360, }, } as never } if (input.includes('/article/publish')) { submitCalls.push(init?.body as URLSearchParams) return { code: 0, data: { pgc_id: 'pgc-1', }, } as never } return {} as never }, async fetchImageBlob() { return new Blob(['image'], { type: 'image/png' }) }, async uploadHtmlImages(html, uploader) { const source = '/api/public/assets/body-token' const target = await uploader(source) return { html: target ? html.split(source).join(target) : html, uploaded: target ? new Map([[source, target]]) : new Map(), } }, ...overrides, } return transport } describe('publishToutiaoArticle', () => { it('submits content with body images replaced by Toutiao image URLs', async () => { const transport = createTransport() const result = await publishToutiaoArticle( { title: '标题', html: '

', publishType: 'publish', }, transport, ) expect(result.success).toBe(true) expect(transport.submitCalls).toHaveLength(1) expect(transport.submitCalls[0]?.get('content')).toContain('https://p3-sign.toutiaoimg.com') expect(transport.submitCalls[0]?.get('content')).not.toContain('/api/public/assets/body-token') }) it('fails before submit when any body image cannot be uploaded to Toutiao', async () => { const transport = createTransport({ async uploadHtmlImages(html) { return { html, uploaded: new Map(), } }, }) const fetchJson = vi.spyOn(transport, 'fetchJson') const result = await publishToutiaoArticle( { title: '标题', html: '

', publishType: 'publish', }, transport, ) expect(result).toMatchObject({ success: false, status: 'failed', code: 'toutiaohao_image_upload_failed', }) expect(fetchJson.mock.calls.some(([input]) => input.includes('/article/publish'))).toBe(false) }) })