summaryrefslogtreecommitdiff
path: root/packages/misskey-js/test
diff options
context:
space:
mode:
authorKagami Sascha Rosylight <saschanaz@outlook.com>2023-03-30 02:33:19 +0200
committerGitHub <noreply@github.com>2023-03-30 09:33:19 +0900
commitcee1d5e2d01359e6d762a10fc67d4e7c1cc830eb (patch)
tree45eab3096b1983ae5267caab4aa4c5eff77b6e5d /packages/misskey-js/test
parentNew Crowdin updates (#10407) (diff)
downloadsharkey-cee1d5e2d01359e6d762a10fc67d4e7c1cc830eb.tar.gz
sharkey-cee1d5e2d01359e6d762a10fc67d4e7c1cc830eb.tar.bz2
sharkey-cee1d5e2d01359e6d762a10fc67d4e7c1cc830eb.zip
chore: integrate misskey-js as a workspace item (git subtree) (#10409)
* Additional changes for the merge * api-misskey-js
Diffstat (limited to 'packages/misskey-js/test')
-rw-r--r--packages/misskey-js/test/api.ts212
-rw-r--r--packages/misskey-js/test/streaming.ts165
2 files changed, 377 insertions, 0 deletions
diff --git a/packages/misskey-js/test/api.ts b/packages/misskey-js/test/api.ts
new file mode 100644
index 0000000000..47c8378014
--- /dev/null
+++ b/packages/misskey-js/test/api.ts
@@ -0,0 +1,212 @@
+import { APIClient, isAPIError } from '../src/api';
+import { enableFetchMocks } from 'jest-fetch-mock';
+
+enableFetchMocks();
+
+function getFetchCall(call: any[]) {
+ const { body, method } = call[1];
+ if (body != null && typeof body != 'string') {
+ throw new Error('invalid body');
+ }
+ return {
+ url: call[0],
+ method: method,
+ body: JSON.parse(body as any)
+ };
+}
+
+describe('API', () => {
+ test('success', async () => {
+ fetchMock.resetMocks();
+ fetchMock.mockResponse(async (req) => {
+ const body = await req.json();
+ if (req.method == 'POST' && req.url == 'https://misskey.test/api/i') {
+ if (body.i === 'TOKEN') {
+ return JSON.stringify({ id: 'foo' });
+ } else {
+ return { status: 400 };
+ }
+ } else {
+ return { status: 404 };
+ }
+ });
+
+ const cli = new APIClient({
+ origin: 'https://misskey.test',
+ credential: 'TOKEN',
+ });
+
+ const res = await cli.request('i');
+
+ expect(res).toEqual({
+ id: 'foo'
+ });
+
+ expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
+ url: 'https://misskey.test/api/i',
+ method: 'POST',
+ body: { i: 'TOKEN' }
+ });
+ });
+
+ test('with params', async () => {
+ fetchMock.resetMocks();
+ fetchMock.mockResponse(async (req) => {
+ const body = await req.json();
+ if (req.method == 'POST' && req.url == 'https://misskey.test/api/notes/show') {
+ if (body.i === 'TOKEN' && body.noteId === 'aaaaa') {
+ return JSON.stringify({ id: 'foo' });
+ } else {
+ return { status: 400 };
+ }
+ } else {
+ return { status: 404 };
+ }
+ });
+
+ const cli = new APIClient({
+ origin: 'https://misskey.test',
+ credential: 'TOKEN',
+ });
+
+ const res = await cli.request('notes/show', { noteId: 'aaaaa' });
+
+ expect(res).toEqual({
+ id: 'foo'
+ });
+
+ expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
+ url: 'https://misskey.test/api/notes/show',
+ method: 'POST',
+ body: { i: 'TOKEN', noteId: 'aaaaa' }
+ });
+ });
+
+ test('204 No Content で null が返る', async () => {
+ fetchMock.resetMocks();
+ fetchMock.mockResponse(async (req) => {
+ if (req.method == 'POST' && req.url == 'https://misskey.test/api/reset-password') {
+ return { status: 204 };
+ } else {
+ return { status: 404 };
+ }
+ });
+
+ const cli = new APIClient({
+ origin: 'https://misskey.test',
+ credential: 'TOKEN',
+ });
+
+ const res = await cli.request('reset-password', { token: 'aaa', password: 'aaa' });
+
+ expect(res).toEqual(null);
+
+ expect(getFetchCall(fetchMock.mock.calls[0])).toEqual({
+ url: 'https://misskey.test/api/reset-password',
+ method: 'POST',
+ body: { i: 'TOKEN', token: 'aaa', password: 'aaa' }
+ });
+ });
+
+ test('インスタンスの credential が指定されていても引数で credential が null ならば null としてリクエストされる', async () => {
+ fetchMock.resetMocks();
+ fetchMock.mockResponse(async (req) => {
+ const body = await req.json();
+ if (req.method == 'POST' && req.url == 'https://misskey.test/api/i') {
+ if (typeof body.i === 'string') {
+ return JSON.stringify({ id: 'foo' });
+ } else {
+ return {
+ status: 401,
+ body: JSON.stringify({
+ error: {
+ message: 'Credential required.',
+ code: 'CREDENTIAL_REQUIRED',
+ id: '1384574d-a912-4b81-8601-c7b1c4085df1',
+ }
+ })
+ };
+ }
+ } else {
+ return { status: 404 };
+ }
+ });
+
+ try {
+ const cli = new APIClient({
+ origin: 'https://misskey.test',
+ credential: 'TOKEN',
+ });
+
+ await cli.request('i', {}, null);
+ } catch (e) {
+ expect(isAPIError(e)).toEqual(true);
+ }
+ });
+
+ test('api error', async () => {
+ fetchMock.resetMocks();
+ fetchMock.mockResponse(async (req) => {
+ return {
+ status: 500,
+ body: JSON.stringify({
+ error: {
+ message: 'Internal error occurred. Please contact us if the error persists.',
+ code: 'INTERNAL_ERROR',
+ id: '5d37dbcb-891e-41ca-a3d6-e690c97775ac',
+ kind: 'server',
+ },
+ })
+ };
+ });
+
+ try {
+ const cli = new APIClient({
+ origin: 'https://misskey.test',
+ credential: 'TOKEN',
+ });
+
+ await cli.request('i');
+ } catch (e: any) {
+ expect(isAPIError(e)).toEqual(true);
+ expect(e.id).toEqual('5d37dbcb-891e-41ca-a3d6-e690c97775ac');
+ }
+ });
+
+ test('network error', async () => {
+ fetchMock.resetMocks();
+ fetchMock.mockAbort();
+
+ try {
+ const cli = new APIClient({
+ origin: 'https://misskey.test',
+ credential: 'TOKEN',
+ });
+
+ await cli.request('i');
+ } catch (e) {
+ expect(isAPIError(e)).toEqual(false);
+ }
+ });
+
+ test('json parse error', async () => {
+ fetchMock.resetMocks();
+ fetchMock.mockResponse(async (req) => {
+ return {
+ status: 500,
+ body: '<html>I AM NOT JSON</html>'
+ };
+ });
+
+ try {
+ const cli = new APIClient({
+ origin: 'https://misskey.test',
+ credential: 'TOKEN',
+ });
+
+ await cli.request('i');
+ } catch (e) {
+ expect(isAPIError(e)).toEqual(false);
+ }
+ });
+});
diff --git a/packages/misskey-js/test/streaming.ts b/packages/misskey-js/test/streaming.ts
new file mode 100644
index 0000000000..913db8b287
--- /dev/null
+++ b/packages/misskey-js/test/streaming.ts
@@ -0,0 +1,165 @@
+import WS from 'jest-websocket-mock';
+import Stream from '../src/streaming';
+
+describe('Streaming', () => {
+ test('useChannel', async () => {
+ const server = new WS('wss://misskey.test/streaming');
+ const stream = new Stream('https://misskey.test', { token: 'TOKEN' });
+ const mainChannelReceived: any[] = [];
+ const main = stream.useChannel('main');
+ main.on('meUpdated', payload => {
+ mainChannelReceived.push(payload);
+ });
+
+ const ws = await server.connected;
+ expect(new URLSearchParams(new URL(ws.url).search).get('i')).toEqual('TOKEN');
+
+ const msg = JSON.parse(await server.nextMessage as string);
+ const mainChannelId = msg.body.id;
+ expect(msg.type).toEqual('connect');
+ expect(msg.body.channel).toEqual('main');
+ expect(mainChannelId != null).toEqual(true);
+
+ server.send(JSON.stringify({
+ type: 'channel',
+ body: {
+ id: mainChannelId,
+ type: 'meUpdated',
+ body: {
+ id: 'foo'
+ }
+ }
+ }));
+
+ expect(mainChannelReceived[0]).toEqual({
+ id: 'foo'
+ });
+
+ stream.close();
+ server.close();
+ });
+
+ test('useChannel with parameters', async () => {
+ const server = new WS('wss://misskey.test/streaming');
+ const stream = new Stream('https://misskey.test', { token: 'TOKEN' });
+ const messagingChannelReceived: any[] = [];
+ const messaging = stream.useChannel('messaging', { otherparty: 'aaa' });
+ messaging.on('message', payload => {
+ messagingChannelReceived.push(payload);
+ });
+
+ const ws = await server.connected;
+ expect(new URLSearchParams(new URL(ws.url).search).get('i')).toEqual('TOKEN');
+
+ const msg = JSON.parse(await server.nextMessage as string);
+ const messagingChannelId = msg.body.id;
+ expect(msg.type).toEqual('connect');
+ expect(msg.body.channel).toEqual('messaging');
+ expect(msg.body.params).toEqual({ otherparty: 'aaa' });
+ expect(messagingChannelId != null).toEqual(true);
+
+ server.send(JSON.stringify({
+ type: 'channel',
+ body: {
+ id: messagingChannelId,
+ type: 'message',
+ body: {
+ id: 'foo'
+ }
+ }
+ }));
+
+ expect(messagingChannelReceived[0]).toEqual({
+ id: 'foo'
+ });
+
+ stream.close();
+ server.close();
+ });
+
+ test('ちゃんとチャンネルごとにidが異なる', async () => {
+ const server = new WS('wss://misskey.test/streaming');
+ const stream = new Stream('https://misskey.test', { token: 'TOKEN' });
+
+ stream.useChannel('messaging', { otherparty: 'aaa' });
+ stream.useChannel('messaging', { otherparty: 'bbb' });
+
+ const ws = await server.connected;
+ expect(new URLSearchParams(new URL(ws.url).search).get('i')).toEqual('TOKEN');
+
+ const msg = JSON.parse(await server.nextMessage as string);
+ const messagingChannelId = msg.body.id;
+ const msg2 = JSON.parse(await server.nextMessage as string);
+ const messagingChannelId2 = msg2.body.id;
+
+ expect(messagingChannelId != null).toEqual(true);
+ expect(messagingChannelId2 != null).toEqual(true);
+ expect(messagingChannelId).not.toEqual(messagingChannelId2);
+
+ stream.close();
+ server.close();
+ });
+
+ test('Connection#send', async () => {
+ const server = new WS('wss://misskey.test/streaming');
+ const stream = new Stream('https://misskey.test', { token: 'TOKEN' });
+
+ const messaging = stream.useChannel('messaging', { otherparty: 'aaa' });
+ messaging.send('read', { id: 'aaa' });
+
+ const ws = await server.connected;
+ expect(new URLSearchParams(new URL(ws.url).search).get('i')).toEqual('TOKEN');
+
+ const connectMsg = JSON.parse(await server.nextMessage as string);
+ const channelId = connectMsg.body.id;
+ const msg = JSON.parse(await server.nextMessage as string);
+
+ expect(msg.type).toEqual('ch');
+ expect(msg.body.id).toEqual(channelId);
+ expect(msg.body.type).toEqual('read');
+ expect(msg.body.body).toEqual({ id: 'aaa' });
+
+ stream.close();
+ server.close();
+ });
+
+ test('Connection#dispose', async () => {
+ const server = new WS('wss://misskey.test/streaming');
+ const stream = new Stream('https://misskey.test', { token: 'TOKEN' });
+ const mainChannelReceived: any[] = [];
+ const main = stream.useChannel('main');
+ main.on('meUpdated', payload => {
+ mainChannelReceived.push(payload);
+ });
+
+ const ws = await server.connected;
+ expect(new URLSearchParams(new URL(ws.url).search).get('i')).toEqual('TOKEN');
+
+ const msg = JSON.parse(await server.nextMessage as string);
+ const mainChannelId = msg.body.id;
+ expect(msg.type).toEqual('connect');
+ expect(msg.body.channel).toEqual('main');
+ expect(mainChannelId != null).toEqual(true);
+ main.dispose();
+
+ server.send(JSON.stringify({
+ type: 'channel',
+ body: {
+ id: mainChannelId,
+ type: 'meUpdated',
+ body: {
+ id: 'foo'
+ }
+ }
+ }));
+
+ expect(mainChannelReceived.length).toEqual(0);
+
+ stream.close();
+ server.close();
+ });
+
+ // TODO: SharedConnection#dispose して一定時間経ったら disconnect メッセージがサーバーに送られてくるかのテスト
+
+ // TODO: チャンネル接続が使いまわされるかのテスト
+});