mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat: add shared cross-platform catbox media upload flow
Added `useFileUpload()` and `uploadToCatbox()` to centralize upload behavior and remove duplicated upload code from `post-form.tsx` and `reply-modal.tsx`. The flow now routes Android to `FileUploader`, Electron to hidden-input + catbox upload, and web to a translated fallback alert with consistent upload UI state.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { uploadToCatbox } from '../catbox-utils';
|
||||
|
||||
describe('uploadToCatbox', () => {
|
||||
const originalFetch = global.fetch;
|
||||
beforeEach(() => {
|
||||
global.fetch = originalFetch;
|
||||
});
|
||||
|
||||
it('POSTs file to catbox API and returns trimmed URL', async () => {
|
||||
const mockFile = new File(['content'], 'test.png', { type: 'image/png' });
|
||||
vi.stubGlobal(
|
||||
'fetch',
|
||||
vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
text: () => Promise.resolve(' https://files.catbox.moe/abc123.png '),
|
||||
}),
|
||||
);
|
||||
|
||||
const url = await uploadToCatbox(mockFile);
|
||||
expect(url).toBe('https://files.catbox.moe/abc123.png');
|
||||
|
||||
const call = (global.fetch as ReturnType<typeof vi.fn>).mock.calls[0];
|
||||
expect(call[0]).toBe('https://catbox.moe/user/api.php');
|
||||
expect(call[1]?.method).toBe('POST');
|
||||
const body = call[1]?.body as FormData;
|
||||
expect(body.get('reqtype')).toBe('fileupload');
|
||||
expect(body.get('fileToUpload')).toBe(mockFile);
|
||||
});
|
||||
|
||||
it('throws Error on non-ok response', async () => {
|
||||
const mockFile = new File(['x'], 'x.txt', { type: 'text/plain' });
|
||||
vi.stubGlobal(
|
||||
'fetch',
|
||||
vi.fn().mockResolvedValue({
|
||||
ok: false,
|
||||
status: 500,
|
||||
statusText: 'Internal Server Error',
|
||||
}),
|
||||
);
|
||||
|
||||
await expect(uploadToCatbox(mockFile)).rejects.toThrow('Upload failed: 500 Internal Server Error');
|
||||
});
|
||||
|
||||
it('throws when fetch rejects with a network error', async () => {
|
||||
const mockFile = new File(['x'], 'x.txt', { type: 'text/plain' });
|
||||
vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new Error('Network down')));
|
||||
|
||||
await expect(uploadToCatbox(mockFile)).rejects.toThrow('Network down');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
const CATBOX_API = 'https://catbox.moe/user/api.php';
|
||||
|
||||
/**
|
||||
* Upload a file to catbox.moe.
|
||||
* @param file - The file to upload
|
||||
* @returns The URL of the uploaded file
|
||||
* @throws Error when the response is not ok
|
||||
*/
|
||||
export async function uploadToCatbox(file: File): Promise<string> {
|
||||
const formData = new FormData();
|
||||
formData.append('reqtype', 'fileupload');
|
||||
formData.append('fileToUpload', file);
|
||||
|
||||
const response = await fetch(CATBOX_API, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Upload failed: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const text = await response.text();
|
||||
return text.trim();
|
||||
}
|
||||
Reference in New Issue
Block a user