diff --git a/packages/social/reddit/src/index.test.ts b/packages/social/reddit/src/index.test.ts index 35819968..1d4c31a6 100644 --- a/packages/social/reddit/src/index.test.ts +++ b/packages/social/reddit/src/index.test.ts @@ -90,4 +90,62 @@ describe('social-reddit posting', () => { subreddit: 'sh1pt', })).rejects.toThrow('RATELIMIT: you are doing that too much'); }); + + it('submits image posts with the image URL payload', async () => { + const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue({ + ok: true, + status: 200, + json: async () => ({ + json: { + data: { + id: 'img123', + url: 'https://www.reddit.com/r/sh1pt/comments/img123/image_drop/', + }, + errors: [], + }, + }), + } as any); + + const ctx = { + ...fakeConnectContext({ REDDIT_ACCESS_TOKEN: 'reddit-token' }), + dryRun: false, + }; + + await adapter.post(ctx as any, { + title: 'Image drop', + body: 'Fallback body', + link: 'https://cdn.example.com/release.png', + }, { + subreddit: 'sh1pt', + kind: 'image', + }); + + const body = new URLSearchParams(String((fetchMock.mock.calls[0]?.[1] as RequestInit).body)); + expect(Object.fromEntries(body)).toMatchObject({ + api_type: 'json', + kind: 'image', + sr: 'sh1pt', + title: 'Image drop', + url: 'https://cdn.example.com/release.png', + }); + expect(body.has('text')).toBe(false); + }); + + it('rejects image posts without a public image URL', async () => { + const fetchMock = vi.spyOn(globalThis, 'fetch'); + const ctx = { + ...fakeConnectContext({ REDDIT_ACCESS_TOKEN: 'reddit-token' }), + dryRun: false, + }; + + await expect(adapter.post(ctx as any, { + title: 'Image drop', + body: 'Fallback body', + }, { + subreddit: 'sh1pt', + kind: 'image', + })).rejects.toThrow('post.link'); + + expect(fetchMock).not.toHaveBeenCalled(); + }); }); diff --git a/packages/social/reddit/src/index.ts b/packages/social/reddit/src/index.ts index 1ad72cdd..5ba1d3d3 100644 --- a/packages/social/reddit/src/index.ts +++ b/packages/social/reddit/src/index.ts @@ -85,6 +85,7 @@ export default defineSocial({ function formatSubmitBody(post: { title?: string; body: string; link?: string }, config: Config): URLSearchParams { const kind = config.kind ?? (post.link ? 'link' : 'self'); + if (kind === 'image' && !post.link) throw new Error('Reddit image submissions require post.link to contain a public image URL'); const body = new URLSearchParams({ api_type: 'json', kind, @@ -92,7 +93,7 @@ function formatSubmitBody(post: { title?: string; body: string; link?: string }, title: post.title ?? '', }); if (config.flairId) body.set('flair_id', config.flairId); - if (kind === 'link') { + if (kind === 'link' || kind === 'image') { body.set('url', post.link ?? post.body); } else { body.set('text', post.body.slice(0, 40_000));