feat(misskey-js): multipart/form-dataのリクエストに対応 (#14147)

* feat(misskey-js): multipart/form-dataのリクエストに対応

* lint

* add test

* Update Changelog

* テストを厳しくする

* lint

* multipart/form-dataではnullのプロパティを弾くように
This commit is contained in:
かっこかり
2024-07-07 14:08:18 +09:00
committed by GitHub
parent 984d582796
commit f119f8c2cc
7 changed files with 537 additions and 14 deletions

View File

@@ -5,13 +5,19 @@ enableFetchMocks();
function getFetchCall(call: any[]) {
const { body, method } = call[1];
if (body != null && typeof body != 'string') {
const contentType = call[1].headers['Content-Type'];
if (
body == null ||
(contentType === 'application/json' && typeof body !== 'string') ||
(contentType === 'multipart/form-data' && !(body instanceof FormData))
) {
throw new Error('invalid body');
}
return {
url: call[0],
method: method,
body: JSON.parse(body as any)
contentType: contentType,
body: body instanceof FormData ? Object.fromEntries(body.entries()) : JSON.parse(body),
};
}
@@ -45,6 +51,7 @@ describe('API', () => {
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: 'https://misskey.test/api/i',
method: 'POST',
contentType: 'application/json',
body: { i: 'TOKEN' }
});
});
@@ -78,10 +85,52 @@ describe('API', () => {
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: 'https://misskey.test/api/notes/show',
method: 'POST',
contentType: 'application/json',
body: { i: 'TOKEN', noteId: 'aaaaa' }
});
});
test('multipart/form-data', async () => {
fetchMock.resetMocks();
fetchMock.mockResponse(async (req) => {
if (req.method == 'POST' && req.url == 'https://misskey.test/api/drive/files/create') {
if (req.headers.get('Content-Type')?.includes('multipart/form-data')) {
return JSON.stringify({ id: 'foo' });
} else {
return { status: 400 };
}
} else {
return { status: 404 };
}
});
const cli = new APIClient({
origin: 'https://misskey.test',
credential: 'TOKEN',
});
const testFile = new File([], 'foo.txt');
const res = await cli.request('drive/files/create', {
file: testFile,
name: null, // nullのパラメータは消える
});
expect(res).toEqual({
id: 'foo'
});
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: 'https://misskey.test/api/drive/files/create',
method: 'POST',
contentType: 'multipart/form-data',
body: {
i: 'TOKEN',
file: testFile,
}
});
});
test('204 No Content で null が返る', async () => {
fetchMock.resetMocks();
fetchMock.mockResponse(async (req) => {
@@ -104,6 +153,7 @@ describe('API', () => {
expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
url: 'https://misskey.test/api/reset-password',
method: 'POST',
contentType: 'application/json',
body: { i: 'TOKEN', token: 'aaa', password: 'aaa' }
});
});