From aca77edeb38649c6a2c7d270ae62705142810f72 Mon Sep 17 00:00:00 2001 From: Neetshin Date: Fri, 21 Jun 2019 00:03:58 +0900 Subject: [PATCH 01/10] Refine gateway's file structure --- src/client/__tests__/masto.spec.ts | 4 ++-- src/client/masto.ts | 2 +- src/client/params.ts | 2 +- src/{client => gateway}/__mocks__/gateway.ts | 0 .../masto-events.ts => gateway/__mocks__/ws-events.ts} | 2 +- src/{client => gateway}/__tests__/gateway.spec.ts | 10 +++++----- src/{client => gateway}/__tests__/utils.spec.ts | 0 .../__tests__/ws-events.spec.ts} | 8 ++++---- src/{client => gateway}/gateway.ts | 4 ++-- src/{client => gateway}/utils.ts | 0 src/{client/masto-events.ts => gateway/ws-events.ts} | 4 ++-- src/index.ts | 6 +++--- 12 files changed, 21 insertions(+), 21 deletions(-) rename src/{client => gateway}/__mocks__/gateway.ts (100%) rename src/{client/__mocks__/masto-events.ts => gateway/__mocks__/ws-events.ts} (58%) rename src/{client => gateway}/__tests__/gateway.spec.ts (96%) rename src/{client => gateway}/__tests__/utils.spec.ts (100%) rename src/{client/__tests__/masto-events.spec.ts => gateway/__tests__/ws-events.spec.ts} (93%) rename src/{client => gateway}/gateway.ts (98%) rename src/{client => gateway}/utils.ts (100%) rename src/{client/masto-events.ts => gateway/ws-events.ts} (95%) diff --git a/src/client/__tests__/masto.spec.ts b/src/client/__tests__/masto.spec.ts index 4dc34408f..7527638f3 100644 --- a/src/client/__tests__/masto.spec.ts +++ b/src/client/__tests__/masto.spec.ts @@ -1,10 +1,10 @@ // tslint:disable // @ts-ignore // prettier-ignore -import { getMock, postMock, deleteMock, patchMock, putMock, streamMock, paginateMock, Gateway } from '../gateway'; +import { getMock, postMock, deleteMock, patchMock, putMock, streamMock, paginateMock, Gateway } from '../../gateway/gateway'; import { Masto } from '../masto'; -jest.mock('../gateway'); +jest.mock('../../gateway/gateway'); describe('Masto', () => { let masto!: Masto; diff --git a/src/client/masto.ts b/src/client/masto.ts index d79d455bf..2b05fde75 100644 --- a/src/client/masto.ts +++ b/src/client/masto.ts @@ -21,8 +21,8 @@ import { Relationship } from '../entities/relationship'; import { Results, ResultsV1 } from '../entities/results'; import { ScheduledStatus } from '../entities/scheduled-status'; import { Status } from '../entities/status'; +import { Gateway } from '../gateway/gateway'; import { available } from './decorators'; -import { Gateway } from './gateway'; import { AddPushSubscriptionParams, CreateAccountParams, diff --git a/src/client/params.ts b/src/client/params.ts index 128f68bb7..d8892c8f2 100644 --- a/src/client/params.ts +++ b/src/client/params.ts @@ -4,7 +4,7 @@ import { FilterContext } from '../entities/filter'; import { NotificationType } from '../entities/notification'; import { PushSubscriptionAlerts } from '../entities/push-subscription'; import { StatusVisibility } from '../entities/status'; -import { GatewayConstructor } from './gateway'; +import { GatewayConstructor } from '../gateway/gateway'; /** Union of acceptable values of form-data for browser and node */ export type IsomorphicFormDataValue = string | Blob | Buffer | ReadStream; diff --git a/src/client/__mocks__/gateway.ts b/src/gateway/__mocks__/gateway.ts similarity index 100% rename from src/client/__mocks__/gateway.ts rename to src/gateway/__mocks__/gateway.ts diff --git a/src/client/__mocks__/masto-events.ts b/src/gateway/__mocks__/ws-events.ts similarity index 58% rename from src/client/__mocks__/masto-events.ts rename to src/gateway/__mocks__/ws-events.ts index 33729dea2..3595a6626 100644 --- a/src/client/__mocks__/masto-events.ts +++ b/src/gateway/__mocks__/ws-events.ts @@ -1,5 +1,5 @@ export const connectMock = jest.fn(); -export const MastoEvents = jest.fn(() => ({ +export const WebSocketEvents = jest.fn(() => ({ connect: connectMock, })); diff --git a/src/client/__tests__/gateway.spec.ts b/src/gateway/__tests__/gateway.spec.ts similarity index 96% rename from src/client/__tests__/gateway.spec.ts rename to src/gateway/__tests__/gateway.spec.ts index e64a72418..78e7275b0 100644 --- a/src/client/__tests__/gateway.spec.ts +++ b/src/gateway/__tests__/gateway.spec.ts @@ -3,13 +3,13 @@ import axios from 'axios'; import FormData from 'form-data'; import { Gateway } from '../gateway'; // @ts-ignore -import { MastoEvents, connectMock } from '../masto-events'; +import { WebSocketEvents, connectMock } from '../ws-events'; import { MastoUnauthorizedError } from '../../errors/masto-unauthorized-error'; import { MastoNotFoundError } from '../../errors/masto-not-found-error'; import { MastoRateLimitError } from '../../errors/masto-rate-limit-error'; jest.mock('axios'); -jest.mock('../masto-events'); +jest.mock('../ws-events'); describe('Gateway', () => { let gateway!: Gateway; @@ -298,19 +298,19 @@ describe('Gateway', () => { ); }); - test('initialize MastoEvents and call connect with given params', async () => { + test('initialize WebSocketEvents and call connect with given params', async () => { const params = { a: 'a', b: 'b' }; await gateway.stream('/', params); expect(connectMock).toBeCalledWith('wss://example.com/?a=a&b=b', []); }); - test('initialize MastoEvents and call connect with access token', async () => { + test('initialize WebSocketEvents and call connect with access token', async () => { gateway.accessToken = 'tokentoken'; await gateway.stream('/'); expect(connectMock).toBeCalledWith('wss://example.com/', ['tokentoken']); }); - test('initialize MastoEvents and call connect with access token as a param for Mastodon < v2.8.4', async () => { + test('initialize WebSocketEvents and call connect with access token as a param for Mastodon < v2.8.4', async () => { gateway.version = '2.8.3'; gateway.accessToken = 'tokentoken'; await gateway.stream('/'); diff --git a/src/client/__tests__/utils.spec.ts b/src/gateway/__tests__/utils.spec.ts similarity index 100% rename from src/client/__tests__/utils.spec.ts rename to src/gateway/__tests__/utils.spec.ts diff --git a/src/client/__tests__/masto-events.spec.ts b/src/gateway/__tests__/ws-events.spec.ts similarity index 93% rename from src/client/__tests__/masto-events.spec.ts rename to src/gateway/__tests__/ws-events.spec.ts index 9f2ee56f4..2198592e7 100644 --- a/src/client/__tests__/masto-events.spec.ts +++ b/src/gateway/__tests__/ws-events.spec.ts @@ -1,6 +1,6 @@ // tslint:disable import WebSocket from 'isomorphic-ws'; -import { MastoEvents } from '../masto-events'; +import { WebSocketEvents } from '../ws-events'; const onMock = jest.fn(); const emitMock = jest.fn(); @@ -21,11 +21,11 @@ jest.mock('isomorphic-ws', () => { })); }); -describe('MastoEvents', () => { - let mastoEvents!: MastoEvents; +describe('WebSocketEvents', () => { + let mastoEvents!: WebSocketEvents; beforeAll(() => { - mastoEvents = new MastoEvents(); + mastoEvents = new WebSocketEvents(); }); test('connect to ws server', async () => { diff --git a/src/client/gateway.ts b/src/gateway/gateway.ts similarity index 98% rename from src/client/gateway.ts rename to src/gateway/gateway.ts index f3a4f012b..b6e505160 100644 --- a/src/client/gateway.ts +++ b/src/gateway/gateway.ts @@ -6,8 +6,8 @@ import { oc } from 'ts-optchain'; import { MastoNotFoundError } from '../errors/masto-not-found-error'; import { MastoRateLimitError } from '../errors/masto-rate-limit-error'; import { MastoUnauthorizedError } from '../errors/masto-unauthorized-error'; -import { MastoEvents } from './masto-events'; import { isAxiosError } from './utils'; +import { WebSocketEvents } from './ws-events'; // tslint:disable-next-line no-import-side-effect import 'isomorphic-form-data'; @@ -333,7 +333,7 @@ export class Gateway { path + (Object.keys(params).length ? `?${querystring.stringify(params)}` : ''); - return new MastoEvents().connect(url, protocols); + return new WebSocketEvents().connect(url, protocols); } /** diff --git a/src/client/utils.ts b/src/gateway/utils.ts similarity index 100% rename from src/client/utils.ts rename to src/gateway/utils.ts diff --git a/src/client/masto-events.ts b/src/gateway/ws-events.ts similarity index 95% rename from src/client/masto-events.ts rename to src/gateway/ws-events.ts index 540f46d79..67e3349e2 100644 --- a/src/client/masto-events.ts +++ b/src/gateway/ws-events.ts @@ -30,7 +30,7 @@ export type EventTypes = keyof EventTypesMap; /** * Mastodon streaming api wrapper */ -export class MastoEvents extends EventEmitter { +export class WebSocketEvents extends EventEmitter { private ws?: WebSocket; /** @@ -40,7 +40,7 @@ export class MastoEvents extends EventEmitter { * @param params URL parameters */ public connect(url: string, protocols?: string | string[]) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.ws = new WebSocket(url, protocols); this.ws.addEventListener('message', this.handleMessage); diff --git a/src/index.ts b/src/index.ts index 889e9c343..09ec30874 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,8 @@ export * from './client/decorators'; -export * from './client/gateway'; +export * from './gateway/gateway'; export * from './client/params'; -export * from './client/masto-events'; -export * from './client/utils'; +export * from './gateway/ws-events'; +export * from './gateway/utils'; export * from './entities/account'; export * from './entities/application'; From 3b1d62368474e16733f9bf5140920d2b661a48d9 Mon Sep 17 00:00:00 2001 From: Neetshin Date: Sat, 22 Jun 2019 16:49:29 +0900 Subject: [PATCH 02/10] WIP: make gateway abstract --- src/client/__tests__/decorators.spec.ts | 12 +- src/client/__tests__/masto.spec.ts | 14 +- src/client/decorators.ts | 2 +- src/client/masto.ts | 266 ++++++++++-------------- src/client/params.ts | 3 - src/gateway/__tests__/gateway.spec.ts | 19 +- src/gateway/gateway.ts | 2 +- 7 files changed, 132 insertions(+), 186 deletions(-) diff --git a/src/client/__tests__/decorators.spec.ts b/src/client/__tests__/decorators.spec.ts index d22763acb..024fa731f 100644 --- a/src/client/__tests__/decorators.spec.ts +++ b/src/client/__tests__/decorators.spec.ts @@ -4,9 +4,7 @@ import { available } from '../decorators'; describe('available', () => { test('throw an error when this.version and param.since is incompatible', () => { class Context { - gateway = { - version: '2.0.0', - }; + public version = '2.0.0'; // @ts-ignore @available({ since: '2.1.0' }) @@ -22,9 +20,7 @@ describe('available', () => { test('throw an error when this.version and param.until is incompatible', () => { class Context { - gateway = { - version: '2.0.0', - }; + public version = '2.0.0'; // @ts-ignore @available({ until: '1.9.0' }) @@ -40,9 +36,7 @@ describe('available', () => { test('not throw an error when this.version and params are compatible', () => { class Context { - gateway = { - version: '2.0.0', - }; + public version = '2.0.0'; // @ts-ignore @available({ sicne: '1.9.0', until: '2.1.0' }) diff --git a/src/client/__tests__/masto.spec.ts b/src/client/__tests__/masto.spec.ts index 7527638f3..7a6e5843f 100644 --- a/src/client/__tests__/masto.spec.ts +++ b/src/client/__tests__/masto.spec.ts @@ -7,12 +7,10 @@ import { Masto } from '../masto'; jest.mock('../../gateway/gateway'); describe('Masto', () => { - let masto!: Masto; + // @ts-ignore + const masto = new Masto({ uri: 'https://example.com' }); beforeEach(() => { - // @ts-ignore - masto = new Masto(new Gateway()); - (getMock as jest.Mock).mockClear(); (postMock as jest.Mock).mockClear(); (deleteMock as jest.Mock).mockClear(); @@ -36,10 +34,9 @@ describe('Masto', () => { }; const masto = await Masto.login(params); - expect((Gateway as any) as jest.Mock).toBeCalledWith(params); expect(getMock).toBeCalledWith(expect.stringContaining('/api/v1/instance')); - expect(masto.gateway.version).toBe('2.8.0'); - expect(masto.gateway.streamingApiUrl).toBe('wss://example.com/stream'); + expect(masto.version).toBe('2.8.0'); + expect(masto.streamingApiUrl).toBe('wss://example.com/stream'); }); test('streamUser', async () => { @@ -349,7 +346,6 @@ describe('Masto', () => { test('fetchFilter', async () => { await masto.fetchFilter('123123'); - expect(getMock).toBeCalledTimes(1); expect(getMock).toMatchSnapshot(); }); @@ -872,7 +868,7 @@ describe('Masto', () => { }); test('fetchDirectTimeline', async () => { - masto.gateway.version = '2.5.0'; + masto.version = '2.5.0'; await masto.fetchDirectTimeline({ max_id: '5', since_id: '3', diff --git a/src/client/decorators.ts b/src/client/decorators.ts index 38987b22a..106698ed0 100644 --- a/src/client/decorators.ts +++ b/src/client/decorators.ts @@ -30,7 +30,7 @@ export const available = (parameters: AvailabeParams): Decorator => ( const { since, until } = parameters; descriptor.value = function(this: Masto, ...args: any[]) { - const version = semver.coerce(this.gateway.version); + const version = semver.coerce(this.version); if (since && version && semver.lt(version, since)) { throw new MastoNotFoundError( diff --git a/src/client/masto.ts b/src/client/masto.ts index 2b05fde75..eec5575a0 100644 --- a/src/client/masto.ts +++ b/src/client/masto.ts @@ -21,7 +21,7 @@ import { Relationship } from '../entities/relationship'; import { Results, ResultsV1 } from '../entities/results'; import { ScheduledStatus } from '../entities/scheduled-status'; import { Status } from '../entities/status'; -import { Gateway } from '../gateway/gateway'; +import { Gateway, GatewayConstructor } from '../gateway/gateway'; import { available } from './decorators'; import { AddPushSubscriptionParams, @@ -33,7 +33,6 @@ import { FetchNotificationsParams, FetchTimelineParams, FollowAccountParams, - LoginParams, ModifyFilterParams, ModifyListAccountsParams, ModifyListParams, @@ -52,19 +51,14 @@ import { VotePollParams, } from './params'; +export type LoginParams = Pick; + /** * Mastodon API client */ -export class Masto { - /** Instance of Gateway */ - public gateway: Gateway; - - /** - * Private constructor - * @param gateway Instance of Gateway - */ - private constructor(gateway: Gateway) { - this.gateway = gateway; +export class Masto extends Gateway { + private constructor(params: GatewayConstructor) { + super(params); } /** @@ -73,12 +67,11 @@ export class Masto { * @return Instance of Mastodon class */ public static async login(params: LoginParams) { - const gateway = new Gateway(params); - const masto = new Masto(gateway); + const masto = new Masto(params); const instance = await masto.fetchInstance(); - gateway.version = instance.version; - gateway.streamingApiUrl = instance.urls.streaming_api; + masto.version = instance.version; + masto.streamingApiUrl = instance.urls.streaming_api; return masto; } @@ -90,7 +83,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public streamUser() { - return this.gateway.stream('/api/v1/streaming', { + return this.stream('/api/v1/streaming', { stream: 'user', }); } @@ -102,7 +95,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public streamPublicTimeline() { - return this.gateway.stream('/api/v1/streaming', { + return this.stream('/api/v1/streaming', { stream: 'public', }); } @@ -114,7 +107,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public streamCommunityTimeline() { - return this.gateway.stream('/api/v1/streaming', { + return this.stream('/api/v1/streaming', { stream: 'public:local', }); } @@ -127,7 +120,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public streamTagTimeline(id: string) { - return this.gateway.stream('/api/v1/streaming', { + return this.stream('/api/v1/streaming', { stream: 'hashtag', tag: id, }); @@ -141,7 +134,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public streamLocalTagTimeline(id: string) { - return this.gateway.stream('/api/v1/streaming', { + return this.stream('/api/v1/streaming', { stream: 'hashtag:local', tag: id, }); @@ -155,7 +148,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public streamListTimeline(id: string) { - return this.gateway.stream('/api/v1/streaming', { + return this.stream('/api/v1/streaming', { stream: 'list', list: id, }); @@ -168,7 +161,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public streamDirectTimeline() { - return this.gateway.stream('/api/v1/streaming', { + return this.stream('/api/v1/streaming', { stream: 'direct', }); } @@ -180,7 +173,7 @@ export class Masto { * @see https://docs.joinmastodon.org/api/authentication/#post-oauth-token */ public fetchAccessToken(params: FetchAccessTokenParams) { - return this.gateway.post('/oauth/token', params); + return this.post('/oauth/token', params); } /** @@ -189,7 +182,7 @@ export class Masto { * @see https://docs.joinmastodon.org/api/authentication/#post-oauth-revoke */ public revokeAccessToken(params: RevokeAccessTokenParams) { - return this.gateway.post('/oauth/revoke', params); + return this.post('/oauth/revoke', params); } /** @@ -200,7 +193,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchAccount(id: string) { - return this.gateway.get(`/api/v1/accounts/${id}`); + return this.get(`/api/v1/accounts/${id}`); } /** @@ -211,7 +204,7 @@ export class Masto { */ @available({ since: '2.8.0' }) public fetchAccountIdentityProofs(id: string) { - return this.gateway.get( + return this.get( `/api/v1/accounts/${id}/identity_proofs`, ); } @@ -223,7 +216,7 @@ export class Masto { */ @available({ since: '2.7.0' }) public createAccount(params: CreateAccountParams) { - return this.gateway.post('/api/v1/accounts', params); + return this.post('/api/v1/accounts', params); } /** @@ -233,9 +226,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public verifyCredentials() { - return this.gateway.get( - '/api/v1/accounts/verify_credentials', - ); + return this.get('/api/v1/accounts/verify_credentials'); } /** @@ -246,7 +237,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public updateCredentials(params?: UpdateCredentialsParams) { - return this.gateway.patch( + return this.patch( '/api/v1/accounts/update_credentials', params, { headers: { 'Content-Type': 'multipart/form-data' } }, @@ -262,10 +253,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchAccountFollowers(id: string, params?: PaginationParams) { - return this.gateway.paginate( - `/api/v1/accounts/${id}/followers`, - params, - ); + return this.paginate(`/api/v1/accounts/${id}/followers`, params); } /** @@ -277,10 +265,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchAccountFollowing(id: string, params?: PaginationParams) { - return this.gateway.paginate( - `/api/v1/accounts/${id}/following`, - params, - ); + return this.paginate(`/api/v1/accounts/${id}/following`, params); } /** @@ -292,10 +277,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchAccountStatuses(id: string, params?: FetchAccountStatusesParams) { - return this.gateway.paginate( - `/api/v1/accounts/${id}/statuses`, - params, - ); + return this.paginate(`/api/v1/accounts/${id}/statuses`, params); } /** @@ -307,10 +289,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public followAccount(id: string, params?: FollowAccountParams) { - return this.gateway.post( - `/api/v1/accounts/${id}/follow`, - params, - ); + return this.post(`/api/v1/accounts/${id}/follow`, params); } /** @@ -321,7 +300,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public unfollowAccount(id: string) { - return this.gateway.post(`/api/v1/accounts/${id}/unfollow`); + return this.post(`/api/v1/accounts/${id}/unfollow`); } /** @@ -332,7 +311,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchAccountRelationships(id: string[]) { - return this.gateway.get(`/api/v1/accounts/relationship`, { + return this.get(`/api/v1/accounts/relationship`, { id, }); } @@ -345,7 +324,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public searchAccounts(params?: SearchAccountsParams) { - return this.gateway.get(`/api/v1/accounts/search`, params); + return this.get(`/api/v1/accounts/search`, params); } /** @@ -356,7 +335,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public createApp(params: CreateAppParams) { - return this.gateway.post(`/api/v1/apps`, params); + return this.post(`/api/v1/apps`, params); } /** @@ -366,7 +345,7 @@ export class Masto { */ @available({ since: '2.0.0' }) public verifyAppCredentials() { - return this.gateway.get(`/api/v1/apps/verify_credentials`); + return this.get(`/api/v1/apps/verify_credentials`); } /** @@ -377,7 +356,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchBlocks(params?: PaginationParams) { - return this.gateway.paginate(`/api/v1/blocks`, params); + return this.paginate(`/api/v1/blocks`, params); } /** @@ -388,7 +367,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public blockAccount(id: string) { - return this.gateway.post(`/api/v1/accounts/${id}/block`); + return this.post(`/api/v1/accounts/${id}/block`); } /** @@ -399,7 +378,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public unblockAccount(id: string) { - return this.gateway.post(`/api/v1/accounts/${id}/unblock`); + return this.post(`/api/v1/accounts/${id}/unblock`); } /** @@ -409,7 +388,7 @@ export class Masto { */ @available({ since: '2.0.0' }) public fetchCustomEmojis() { - return this.gateway.get(`/api/v1/custom_emojis`); + return this.get(`/api/v1/custom_emojis`); } /** @@ -420,7 +399,7 @@ export class Masto { */ @available({ since: '1.4.0' }) public fetchDomainBlocks(params?: PaginationParams) { - return this.gateway.paginate(`/api/v1/domain_blocks`, params); + return this.paginate(`/api/v1/domain_blocks`, params); } /** @@ -431,7 +410,7 @@ export class Masto { */ @available({ since: '1.4.0' }) public blockDomain(domain: string) { - return this.gateway.post(`/api/v1/domain_blocks`, { + return this.post(`/api/v1/domain_blocks`, { domain, }); } @@ -444,7 +423,7 @@ export class Masto { */ @available({ since: '1.4.0' }) public unblockDomain(domain: string) { - return this.gateway.delete(`/api/v1/domain_blocks`, { + return this.delete(`/api/v1/domain_blocks`, { domain, }); } @@ -456,7 +435,7 @@ export class Masto { */ @available({ since: '2.5.0' }) public fetchEndorsements(params?: PaginationParams) { - return this.gateway.paginate(`/api/v1/endorsements`, params); + return this.paginate(`/api/v1/endorsements`, params); } /** @@ -467,7 +446,7 @@ export class Masto { */ @available({ since: '2.5.0' }) public pinAccount(id: string) { - return this.gateway.post(`/api/v1/accounts/${id}/pin`); + return this.post(`/api/v1/accounts/${id}/pin`); } /** @@ -478,7 +457,7 @@ export class Masto { */ @available({ since: '2.5.0' }) public unpinAccount(id: string) { - return this.gateway.post(`/api/v1/accounts/${id}/unpin`); + return this.post(`/api/v1/accounts/${id}/unpin`); } /** @@ -489,7 +468,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchFavourites(params?: PaginationParams) { - return this.gateway.paginate(`/api/v1/favourites`, params); + return this.paginate(`/api/v1/favourites`, params); } /** @@ -500,7 +479,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public favouriteStatus(id: string) { - return this.gateway.post(`/api/v1/statuses/${id}/favourite`); + return this.post(`/api/v1/statuses/${id}/favourite`); } /** @@ -511,7 +490,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public unfavouriteStatus(id: string) { - return this.gateway.post(`/api/v1/statuses/${id}/unfavourite`); + return this.post(`/api/v1/statuses/${id}/unfavourite`); } /** @@ -521,7 +500,7 @@ export class Masto { */ @available({ since: '2.4.3' }) public fetchFilters() { - return this.gateway.get(`/api/v1/filters`); + return this.get(`/api/v1/filters`); } /** @@ -532,7 +511,7 @@ export class Masto { */ @available({ since: '2.4.3' }) public fetchFilter(id: string) { - return this.gateway.get(`/api/v1/filters/${id}`); + return this.get(`/api/v1/filters/${id}`); } /** @@ -543,7 +522,7 @@ export class Masto { */ @available({ since: '2.4.3' }) public createFiler(params?: ModifyFilterParams) { - return this.gateway.post(`/api/v1/filters`, params); + return this.post(`/api/v1/filters`, params); } /** @@ -555,7 +534,7 @@ export class Masto { */ @available({ since: '2.4.3' }) public updateFilter(id: string, params?: ModifyFilterParams) { - return this.gateway.put(`/api/v1/filters/${id}`, params); + return this.put(`/api/v1/filters/${id}`, params); } /** @@ -566,7 +545,7 @@ export class Masto { */ @available({ since: '2.4.3' }) public removeFilter(id: string) { - return this.gateway.delete(`/api/v1/filters/${id}`); + return this.delete(`/api/v1/filters/${id}`); } /** @@ -577,7 +556,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchFollowRequests(params?: PaginationParams) { - return this.gateway.paginate(`/api/v1/follow_requests`, params); + return this.paginate(`/api/v1/follow_requests`, params); } /** @@ -588,7 +567,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public authorizeFollowRequest(id: string) { - return this.gateway.post(`/api/v1/follow_requests/${id}/authorize`); + return this.post(`/api/v1/follow_requests/${id}/authorize`); } /** @@ -599,7 +578,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public rejectFollowRequest(id: string) { - return this.gateway.post(`/api/v1/follow_requests/${id}/reject`); + return this.post(`/api/v1/follow_requests/${id}/reject`); } /** @@ -609,7 +588,7 @@ export class Masto { */ @available({ since: '2.4.3' }) public fetchSuggestions() { - return this.gateway.get('/api/v1/suggestions'); + return this.get('/api/v1/suggestions'); } /** @@ -620,7 +599,7 @@ export class Masto { */ @available({ since: '2.4.3' }) public removeSuggestion(id: string) { - return this.gateway.delete(`/api/v1/suggestions/${id}`); + return this.delete(`/api/v1/suggestions/${id}`); } /** @@ -630,7 +609,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchInstance() { - return this.gateway.get('/api/v1/instance'); + return this.get('/api/v1/instance'); } /** @@ -640,7 +619,7 @@ export class Masto { */ @available({ since: '2.1.2' }) public fetchInstancesPeers() { - return this.gateway.get('/api/v1/instance/peers'); + return this.get('/api/v1/instance/peers'); } /** @@ -650,7 +629,7 @@ export class Masto { */ @available({ since: '2.1.2' }) public fetchInstanceActivity() { - return this.gateway.get('/api/v1/instance/activity'); + return this.get('/api/v1/instance/activity'); } /** @@ -660,7 +639,7 @@ export class Masto { */ @available({ since: '2.1.0' }) public fetchLists() { - return this.gateway.get('/api/v1/lists'); + return this.get('/api/v1/lists'); } /** @@ -671,7 +650,7 @@ export class Masto { */ @available({ since: '2.1.0' }) public fetchAccountLists(id: string) { - return this.gateway.get(`/api/v1/accounts/${id}/lists`); + return this.get(`/api/v1/accounts/${id}/lists`); } /** @@ -683,10 +662,7 @@ export class Masto { */ @available({ since: '2.1.0' }) public fetchListAccounts(id: string, params?: PaginationParams) { - return this.gateway.paginate( - `/api/v1/list/${id}/accounts`, - params, - ); + return this.paginate(`/api/v1/list/${id}/accounts`, params); } /** @@ -697,7 +673,7 @@ export class Masto { */ @available({ since: '2.1.0' }) public fetchList(id: string) { - return this.gateway.get(`/api/v1/lists/${id}`); + return this.get(`/api/v1/lists/${id}`); } /** @@ -708,7 +684,7 @@ export class Masto { */ @available({ since: '2.1.0' }) public createList(params: ModifyListParams) { - return this.gateway.post('/api/v1/lists', params); + return this.post('/api/v1/lists', params); } /** @@ -720,7 +696,7 @@ export class Masto { */ @available({ since: '2.1.0' }) public updateList(id: string, params: ModifyListParams) { - return this.gateway.put(`/api/v1/lists/${id}`, params); + return this.put(`/api/v1/lists/${id}`, params); } /** @@ -731,7 +707,7 @@ export class Masto { */ @available({ since: '2.1.0' }) public removeList(id: string) { - return this.gateway.delete(`/api/v1/lists/${id}`); + return this.delete(`/api/v1/lists/${id}`); } /** @@ -743,7 +719,7 @@ export class Masto { */ @available({ since: '2.1.0' }) public addAccountToList(id: string, params: ModifyListAccountsParams) { - return this.gateway.post(`/api/v1/lists/${id}/accounts`, params); + return this.post(`/api/v1/lists/${id}/accounts`, params); } /** @@ -755,7 +731,7 @@ export class Masto { */ @available({ since: '2.1.0' }) public removeAccountFromList(id: string, params: ModifyListAccountsParams) { - return this.gateway.delete(`/api/v1/lists/${id}/accounts`, params); + return this.delete(`/api/v1/lists/${id}/accounts`, params); } /** @@ -766,7 +742,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public uploadMediaAttachment(params: UploadMediaAttachmentParams) { - return this.gateway.post('/api/v1/media', params, { + return this.post('/api/v1/media', params, { headers: { 'Content-Type': 'multipart/form-data' }, }); } @@ -783,7 +759,7 @@ export class Masto { id: string, params: UpdateMediaAttachmentParams, ) { - return this.gateway.put(`/api/v1/media/${id}`, params); + return this.put(`/api/v1/media/${id}`, params); } /** @@ -794,7 +770,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchMutes(params?: PaginationParams) { - return this.gateway.paginate('/api/v1/mutes', params); + return this.paginate('/api/v1/mutes', params); } /** @@ -806,10 +782,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public muteAccount(id: string, params: MuteAccountParams) { - return this.gateway.post( - `/api/v1/accounts/${id}/mute`, - params, - ); + return this.post(`/api/v1/accounts/${id}/mute`, params); } /** @@ -820,7 +793,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public unmuteAccount(id: string) { - return this.gateway.post(`/api/v1/accounts/${id}/unmute`); + return this.post(`/api/v1/accounts/${id}/unmute`); } /** @@ -831,7 +804,7 @@ export class Masto { */ @available({ since: '1.4.2' }) public muteStatus(id: string) { - return this.gateway.post(`/api/v1/statuses/${id}/mute`); + return this.post(`/api/v1/statuses/${id}/mute`); } /** @@ -842,7 +815,7 @@ export class Masto { */ @available({ since: '1.4.2' }) public unmuteStatus(id: string) { - return this.gateway.post(`/api/v1/statuses/${id}/unmute`); + return this.post(`/api/v1/statuses/${id}/unmute`); } /** @@ -853,7 +826,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchNotifications(params?: FetchNotificationsParams) { - return this.gateway.get('/api/v1/notifications', params); + return this.get('/api/v1/notifications', params); } /** @@ -864,7 +837,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchNotification(id: string) { - return this.gateway.get(`/api/v1/notifications/${id}`); + return this.get(`/api/v1/notifications/${id}`); } /** @@ -874,7 +847,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public clearNotifications() { - return this.gateway.post('/api/v1/notifications/clear'); + return this.post('/api/v1/notifications/clear'); } /** @@ -885,7 +858,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public dissmissNotification(id: string) { - return this.gateway.post('/api/v1/notifications/dismiss', { + return this.post('/api/v1/notifications/dismiss', { id, }); } @@ -898,10 +871,7 @@ export class Masto { */ @available({ since: '2.4.0' }) public addPushSubscription(params: AddPushSubscriptionParams) { - return this.gateway.post( - '/api/v1/push/subscription', - params, - ); + return this.post('/api/v1/push/subscription', params); } /** @@ -911,7 +881,7 @@ export class Masto { */ @available({ since: '2.4.0' }) public fetchPushSubscription() { - return this.gateway.get('/api/v1/push/subscription'); + return this.get('/api/v1/push/subscription'); } /** @@ -922,10 +892,7 @@ export class Masto { */ @available({ since: '2.4.0' }) public updatePushSubscription(params: UpdatePushSubscriptionParams) { - return this.gateway.put( - '/api/v1/push/subscription', - params, - ); + return this.put('/api/v1/push/subscription', params); } /** @@ -935,7 +902,7 @@ export class Masto { */ @available({ since: '2.4.0' }) public removePushSubscription() { - return this.gateway.delete('/api/v1/push/subscription'); + return this.delete('/api/v1/push/subscription'); } /** @@ -946,7 +913,7 @@ export class Masto { */ @available({ since: '2.8.0' }) public fetchPoll(id: string) { - return this.gateway.get(`/api/v1/polls/${id}`); + return this.get(`/api/v1/polls/${id}`); } /** @@ -958,7 +925,7 @@ export class Masto { */ @available({ since: '2.8.0' }) public votePoll(id: string, params: VotePollParams) { - return this.gateway.post(`/api/v1/polls/${id}/votes`, params); + return this.post(`/api/v1/polls/${id}/votes`, params); } /** @@ -969,7 +936,7 @@ export class Masto { */ @available({ since: '1.1.0' }) public reportAccount(params: ReportAccountParams) { - return this.gateway.post('/api/v1/reports', params); + return this.post('/api/v1/reports', params); } /** @@ -979,7 +946,7 @@ export class Masto { */ @available({ since: '2.7.0' }) public fetchScheduledStatuses() { - return this.gateway.get('/api/v1/scheduled_statuses'); + return this.get('/api/v1/scheduled_statuses'); } /** @@ -990,9 +957,7 @@ export class Masto { */ @available({ since: '2.7.0' }) public fetchScheduledStatus(id: string) { - return this.gateway.get( - `/api/v1/scheduled_statuses/${id}`, - ); + return this.get(`/api/v1/scheduled_statuses/${id}`); } /** @@ -1007,7 +972,7 @@ export class Masto { id: string, params: UpdateScheduledStatusParams, ) { - return this.gateway.put( + return this.put( `/api/v1/scheduled_statuses/${id}`, params, ); @@ -1021,7 +986,7 @@ export class Masto { */ @available({ since: '2.7.0' }) public removeScheduledStatus(id: string) { - return this.gateway.delete(`/api/v1/scheduled_statuses/${id}`); + return this.delete(`/api/v1/scheduled_statuses/${id}`); } /** @@ -1036,7 +1001,7 @@ export class Masto { params: SearchParams, version = 'v2' as V, ) { - return this.gateway.paginate( + return this.paginate( `/api/${version}/search`, params, ); @@ -1050,7 +1015,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchStatus(id: string) { - return this.gateway.get(`/api/v1/statuses/${id}`); + return this.get(`/api/v1/statuses/${id}`); } /** @@ -1061,7 +1026,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchStatusContext(id: string) { - return this.gateway.get(`/api/v1/statuses/${id}/context`); + return this.get(`/api/v1/statuses/${id}/context`); } /** @@ -1071,7 +1036,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchStatusCard(id: string) { - return this.gateway.get(`/api/v1/statuses/${id}/card`); + return this.get(`/api/v1/statuses/${id}/card`); } /** @@ -1083,7 +1048,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchStatusRebloggedBy(id: string, params?: PaginationParams) { - return this.gateway.paginate( + return this.paginate( `/api/v1/statuses/${id}/reblogged_by`, params, ); @@ -1098,7 +1063,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchStatusFavouritedBy(id: string, params?: PaginationParams) { - return this.gateway.paginate( + return this.paginate( `/api/v1/statuses/${id}/favourited_by`, params, ); @@ -1114,12 +1079,12 @@ export class Masto { @available({ since: '0.0.0' }) public createStatus(params?: CreateStatusParams, idempotencyKey?: string) { if (idempotencyKey) { - return this.gateway.post('/api/v1/statuses', params, { + return this.post('/api/v1/statuses', params, { headers: { 'Idempotency-Key': idempotencyKey }, }); } - return this.gateway.post('/api/v1/statuses', params); + return this.post('/api/v1/statuses', params); } /** @@ -1130,7 +1095,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public removeStatus(id: string) { - return this.gateway.delete(`/api/v1/statuses/${id}`); + return this.delete(`/api/v1/statuses/${id}`); } /** @@ -1141,7 +1106,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public reblogStatus(id: string, params?: ReblogStatusParams) { - return this.gateway.post(`/api/v1/statuses/${id}/reblog`, params); + return this.post(`/api/v1/statuses/${id}/reblog`, params); } /** @@ -1152,7 +1117,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public unreblogStatus(id: string) { - return this.gateway.post(`/api/v1/statuses/${id}/unreblog`); + return this.post(`/api/v1/statuses/${id}/unreblog`); } /** @@ -1163,7 +1128,7 @@ export class Masto { */ @available({ since: '1.6.0' }) public pinStatus(id: string) { - return this.gateway.post(`/api/v1/statuses/${id}/pin`); + return this.post(`/api/v1/statuses/${id}/pin`); } /** @@ -1174,7 +1139,7 @@ export class Masto { */ @available({ since: '1.6.0' }) public unpinStatus(id: string) { - return this.gateway.post(`/api/v1/statuses/${id}/unpin`); + return this.post(`/api/v1/statuses/${id}/unpin`); } /** @@ -1185,7 +1150,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchHomeTimeline(params?: FetchTimelineParams) { - return this.gateway.paginate('/api/v1/timelines/home', params); + return this.paginate('/api/v1/timelines/home', params); } /** @@ -1196,7 +1161,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchCommunityTimeline(params?: FetchTimelineParams) { - return this.gateway.paginate('/api/v1/timelines/public', { + return this.paginate('/api/v1/timelines/public', { local: true, ...params, }); @@ -1210,7 +1175,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchPublicTimeline(params?: FetchTimelineParams) { - return this.gateway.paginate('/api/v1/timelines/public', params); + return this.paginate('/api/v1/timelines/public', params); } /** @@ -1222,10 +1187,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public fetchTagTimeline(id: string, params?: FetchTimelineParams) { - return this.gateway.paginate( - `/api/v1/timelines/tag/${id}`, - params, - ); + return this.paginate(`/api/v1/timelines/tag/${id}`, params); } /** @@ -1237,10 +1199,7 @@ export class Masto { */ @available({ since: '2.1.0' }) public fetchListTimeline(id: string, params?: FetchTimelineParams) { - return this.gateway.paginate( - `/api/v1/timelines/list/${id}`, - params, - ); + return this.paginate(`/api/v1/timelines/list/${id}`, params); } /** @@ -1249,7 +1208,7 @@ export class Masto { */ @available({ since: '0.0.0', until: '2.5.2' }) public fetchDirectTimeline(params?: FetchTimelineParams) { - return this.gateway.paginate('/api/v1/timelines/direct', params); + return this.paginate('/api/v1/timelines/direct', params); } /** @@ -1258,10 +1217,7 @@ export class Masto { */ @available({ since: '2.6.0' }) public fetchConversations(params?: PaginationParams) { - return this.gateway.paginate( - '/api/v1/conversations', - params, - ); + return this.paginate('/api/v1/conversations', params); } /** @@ -1272,7 +1228,7 @@ export class Masto { */ @available({ since: '0.0.0' }) public followAccountByUsername(uri: string) { - return this.gateway.post('/api/v1/follows', { uri }); + return this.post('/api/v1/follows', { uri }); } /** @@ -1282,6 +1238,6 @@ export class Masto { */ @available({ since: '2.8.0' }) public fetchPreferences() { - return this.gateway.get('/api/v1/preferences'); + return this.get('/api/v1/preferences'); } } diff --git a/src/client/params.ts b/src/client/params.ts index d8892c8f2..cfd2600ee 100644 --- a/src/client/params.ts +++ b/src/client/params.ts @@ -4,13 +4,10 @@ import { FilterContext } from '../entities/filter'; import { NotificationType } from '../entities/notification'; import { PushSubscriptionAlerts } from '../entities/push-subscription'; import { StatusVisibility } from '../entities/status'; -import { GatewayConstructor } from '../gateway/gateway'; /** Union of acceptable values of form-data for browser and node */ export type IsomorphicFormDataValue = string | Blob | Buffer | ReadStream; -export type LoginParams = Pick; - export interface PaginationParams { /** Get a list of items with ID less than this value */ max_id?: string | null; diff --git a/src/gateway/__tests__/gateway.spec.ts b/src/gateway/__tests__/gateway.spec.ts index 78e7275b0..086383508 100644 --- a/src/gateway/__tests__/gateway.spec.ts +++ b/src/gateway/__tests__/gateway.spec.ts @@ -1,7 +1,8 @@ // tslint:disable import axios from 'axios'; import FormData from 'form-data'; -import { Gateway } from '../gateway'; +// @ts-ignore +import { Gateway, getMock } from '../gateway'; // @ts-ignore import { WebSocketEvents, connectMock } from '../ws-events'; import { MastoUnauthorizedError } from '../../errors/masto-unauthorized-error'; @@ -12,10 +13,12 @@ jest.mock('axios'); jest.mock('../ws-events'); describe('Gateway', () => { - let gateway!: Gateway; + class InheritedGateway extends Gateway {} + + let gateway!: InheritedGateway; beforeEach(() => { - gateway = new Gateway({ + gateway = new InheritedGateway({ uri: 'https://example.com', version: '99.9.9', streamingApiUrl: 'wss://example.com', @@ -28,7 +31,7 @@ describe('Gateway', () => { }); test('streamingApiUrl has been set if construct with streamingApiUrl', () => { - gateway = new Gateway({ + gateway = new InheritedGateway({ uri: 'https://example.com', streamingApiUrl: 'wss://example.com', }); @@ -36,7 +39,7 @@ describe('Gateway', () => { }); test('version has been set if construct with version ', () => { - gateway = new Gateway({ + gateway = new InheritedGateway({ uri: 'https://example.com', version: '1.2.3', }); @@ -44,7 +47,7 @@ describe('Gateway', () => { }); test('accessToken has been set if construct with accessToken', () => { - gateway = new Gateway({ + gateway = new InheritedGateway({ uri: 'https://example.com', accessToken: 'token token', }); @@ -52,7 +55,7 @@ describe('Gateway', () => { }); test('this._uri accessor works', () => { - gateway = new Gateway({ + gateway = new InheritedGateway({ uri: 'https://example.com/aaa', }); gateway.uri = 'https://example.com/bbb'; @@ -60,7 +63,7 @@ describe('Gateway', () => { }); test('this._streamingApiUrl accessor works', () => { - gateway = new Gateway({ + gateway = new InheritedGateway({ uri: 'wss://example.com/aaa', }); gateway.uri = 'wss://example.com/bbb'; diff --git a/src/gateway/gateway.ts b/src/gateway/gateway.ts index b6e505160..f00b697a9 100644 --- a/src/gateway/gateway.ts +++ b/src/gateway/gateway.ts @@ -36,7 +36,7 @@ export type PaginateNextOptions = { * Mastodon network request wrapper * @param params Optional params */ -export class Gateway { +export abstract class Gateway { /** URI of the instance */ private _uri = ''; /** Streaming API URL of the instance */ From b1fd87662bfc5345feacdca7f806146514f45b68 Mon Sep 17 00:00:00 2001 From: Neetshin Date: Sat, 22 Jun 2019 17:48:38 +0900 Subject: [PATCH 03/10] Update unit tests --- .../__snapshots__/masto.spec.ts.snap | 1616 +++++++++++++---- src/client/__tests__/masto.spec.ts | 546 +++--- src/gateway/gateway.ts | 2 +- 3 files changed, 1524 insertions(+), 640 deletions(-) diff --git a/src/client/__tests__/__snapshots__/masto.spec.ts.snap b/src/client/__tests__/__snapshots__/masto.spec.ts.snap index 02e6b0d63..642592733 100644 --- a/src/client/__tests__/__snapshots__/masto.spec.ts.snap +++ b/src/client/__tests__/__snapshots__/masto.spec.ts.snap @@ -4,13 +4,16 @@ exports[`Masto addAccountToList 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/lists/123123/accounts", Object { - "account_ids": Array [ - "123", - "456", - "678", + "data": "{\\"account_ids\\":[\\"123\\",\\"456\\",\\"678\\"]}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], ], + "url": "https://example.com/api/v1/lists/123123/accounts", }, ], ], @@ -27,23 +30,16 @@ exports[`Masto addPushSubscription 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/push/subscription", Object { - "data": Object { - "alerts": Object { - "favourite": true, - "follow": true, - "mention": true, - "reblog": true, - }, - }, - "subscription": Object { - "endpoint": "https://example.com", - "keys": Object { - "auth": "yyyy", - "p256dh": "xxxx", - }, + "data": "{\\"subscription\\":{\\"endpoint\\":\\"https://example.com\\",\\"keys\\":{\\"p256dh\\":\\"xxxx\\",\\"auth\\":\\"yyyy\\"}},\\"data\\":{\\"alerts\\":{\\"follow\\":true,\\"favourite\\":true,\\"reblog\\":true,\\"mention\\":true}}}", + "headers": Object { + "Content-Type": "application/json", }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/push/subscription", }, ], ], @@ -60,7 +56,17 @@ exports[`Masto authorizeFollowRequest 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/follow_requests/123123/authorize", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/follow_requests/123123/authorize", + }, ], ], "results": Array [ @@ -76,7 +82,17 @@ exports[`Masto blockAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123/block", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123/block", + }, ], ], "results": Array [ @@ -92,9 +108,16 @@ exports[`Masto blockDomain 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/domain_blocks", Object { - "domain": "example.com", + "data": "{\\"domain\\":\\"example.com\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/domain_blocks", }, ], ], @@ -111,7 +134,17 @@ exports[`Masto clearNotifications 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/notifications/clear", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/notifications/clear", + }, ], ], "results": Array [ @@ -127,12 +160,16 @@ exports[`Masto createAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts", Object { - "agreement": true, - "email": "example@example.com", - "password": "password", - "username": "username", + "data": "{\\"username\\":\\"username\\",\\"password\\":\\"password\\",\\"email\\":\\"example@example.com\\",\\"agreement\\":true}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts", }, ], ], @@ -149,12 +186,16 @@ exports[`Masto createApp 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/apps", Object { - "client_name": "My Client", - "redirect_uris": "https://example.com", - "scopes": "write read", - "website": "https://example.com", + "data": "{\\"client_name\\":\\"My Client\\",\\"redirect_uris\\":\\"https://example.com\\",\\"scopes\\":\\"write read\\",\\"website\\":\\"https://example.com\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/apps", }, ], ], @@ -171,18 +212,16 @@ exports[`Masto createFiler 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/filters", Object { - "context": Array [ - "home", - "notifications", - "public", - "thread", + "data": "{\\"phrase\\":\\"Twitter\\",\\"context\\":[\\"home\\",\\"notifications\\",\\"public\\",\\"thread\\"],\\"irreversible\\":true,\\"whole_word\\":true,\\"expires_in\\":3600000}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], ], - "expires_in": 3600000, - "irreversible": true, - "phrase": "Twitter", - "whole_word": true, + "url": "https://example.com/api/v1/filters", }, ], ], @@ -199,9 +238,16 @@ exports[`Masto createList 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/lists", Object { - "title": "My list", + "data": "{\\"title\\":\\"My list\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/lists", }, ], ], @@ -218,14 +264,17 @@ exports[`Masto createStatus with Idempotency-Key 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses", - Object { - "status": "Too!", - }, Object { + "data": "{\\"status\\":\\"Too!\\"}", "headers": Object { + "Content-Type": "application/json", "Idempotency-Key": "59fe7e30-1a74-4050-8af7-5a8c7a224794", }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses", }, ], ], @@ -242,25 +291,16 @@ exports[`Masto createStatus with content 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses", Object { - "in_reply_to_id": "123123", - "language": "en", - "poll": Object { - "expires_in": 60000, - "hide_totals": true, - "multiple": false, - "options": Array [ - "xxx", - "yyy", - "zzz", - ], + "data": "{\\"status\\":\\"Toot!\\",\\"in_reply_to_id\\":\\"123123\\",\\"poll\\":{\\"options\\":[\\"xxx\\",\\"yyy\\",\\"zzz\\"],\\"expires_in\\":60000,\\"multiple\\":false,\\"hide_totals\\":true},\\"sensitive\\":false,\\"spoiler_text\\":\\"spoiler\\",\\"visibility\\":\\"direct\\",\\"scheduled_at\\":\\"2019-03-28T04:39:31.121Z\\",\\"language\\":\\"en\\"}", + "headers": Object { + "Content-Type": "application/json", }, - "scheduled_at": "2019-03-28T04:39:31.121Z", - "sensitive": false, - "spoiler_text": "spoiler", - "status": "Toot!", - "visibility": "direct", + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses", }, ], ], @@ -277,12 +317,16 @@ exports[`Masto createStatus with media ids 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses", Object { - "media_ids": Array [ - "123", - "456", + "data": "{\\"media_ids\\":[\\"123\\",\\"456\\"]}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], ], + "url": "https://example.com/api/v1/statuses", }, ], ], @@ -299,9 +343,16 @@ exports[`Masto dissmissNotification 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/notifications/dismiss", Object { - "id": "123123", + "data": "{\\"id\\":\\"123123\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/notifications/dismiss", }, ], ], @@ -318,7 +369,17 @@ exports[`Masto favouriteStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/favourite", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/favourite", + }, ], ], "results": Array [ @@ -334,13 +395,16 @@ exports[`Masto fetchAccessToken with authorization code 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/oauth/token", Object { - "client_id": "123123123", - "client_secret": "456456456", - "code": "789789789", - "grant_type": "authorization_code", - "redirect_uri": "https://example.com", + "data": "{\\"grant_type\\":\\"authorization_code\\",\\"code\\":\\"789789789\\",\\"redirect_uri\\":\\"https://example.com\\",\\"client_id\\":\\"123123123\\",\\"client_secret\\":\\"456456456\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/oauth/token", }, ], ], @@ -357,11 +421,16 @@ exports[`Masto fetchAccessToken with password 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/oauth/token", Object { - "grant_type": "password", - "password": "password", - "username": "username", + "data": "{\\"grant_type\\":\\"password\\",\\"username\\":\\"username\\",\\"password\\":\\"password\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/oauth/token", }, ], ], @@ -378,7 +447,18 @@ exports[`Masto fetchAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123123", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123123", + }, ], ], "results": Array [ @@ -394,19 +474,29 @@ exports[`Masto fetchAccountFollowers 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123123/followers", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123123/followers", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -416,19 +506,29 @@ exports[`Masto fetchAccountFollowing 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123123/following", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123123/following", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -438,7 +538,18 @@ exports[`Masto fetchAccountIdentityProofs 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123123/identity_proofs", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123123/identity_proofs", + }, ], ], "results": Array [ @@ -454,7 +565,18 @@ exports[`Masto fetchAccountLists 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123/lists", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123/lists", + }, ], ], "results": Array [ @@ -470,12 +592,22 @@ exports[`Masto fetchAccountRelationships 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/relationship", Object { - "id": Array [ - "123123", - "456456", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "id": Array [ + "123123", + "456456", + ], + }, + "transformResponse": Array [ + [Function], ], + "url": "https://example.com/api/v1/accounts/relationship", }, ], ], @@ -492,19 +624,29 @@ exports[`Masto fetchAccountStatuses 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123123/statuses", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123123/statuses", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -514,19 +656,29 @@ exports[`Masto fetchBlocks 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/blocks", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/blocks", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -536,20 +688,30 @@ exports[`Masto fetchCommunityTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/timelines/public", Object { - "limit": 10, - "local": true, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "local": true, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/timelines/public", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -559,19 +721,29 @@ exports[`Masto fetchConversations 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/conversations", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/conversations", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -581,7 +753,18 @@ exports[`Masto fetchCustomEmojis 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/custom_emojis", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/custom_emojis", + }, ], ], "results": Array [ @@ -597,19 +780,29 @@ exports[`Masto fetchDirectTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/timelines/direct", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/timelines/direct", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -619,14 +812,24 @@ exports[`Masto fetchDomainBlocks 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/domain_blocks", - undefined, + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": undefined, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/domain_blocks", + }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -636,19 +839,29 @@ exports[`Masto fetchEndorsements 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/endorsements", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/endorsements", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -658,19 +871,29 @@ exports[`Masto fetchFavourites 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/favourites", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/favourites", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -680,7 +903,18 @@ exports[`Masto fetchFilter 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/filters/123123", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/filters/123123", + }, ], ], "results": Array [ @@ -696,7 +930,18 @@ exports[`Masto fetchFilters 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/filters", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/filters", + }, ], ], "results": Array [ @@ -712,19 +957,29 @@ exports[`Masto fetchFollowRequests 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/follow_requests", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/follow_requests", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -734,19 +989,29 @@ exports[`Masto fetchHomeTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/timelines/home", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/timelines/home", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -756,7 +1021,18 @@ exports[`Masto fetchInstance 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/suggestions", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/suggestions", + }, ], ], "results": Array [ @@ -772,7 +1048,18 @@ exports[`Masto fetchInstanceActivity 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/instance/activity", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/instance/activity", + }, ], ], "results": Array [ @@ -788,7 +1075,18 @@ exports[`Masto fetchInstancesPeers 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/instance/peers", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/instance/peers", + }, ], ], "results": Array [ @@ -804,7 +1102,18 @@ exports[`Masto fetchList 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/lists/123123", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/lists/123123", + }, ], ], "results": Array [ @@ -820,19 +1129,29 @@ exports[`Masto fetchListAccounts 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/list/123123/accounts", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/list/123123/accounts", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -842,19 +1161,29 @@ exports[`Masto fetchListTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/timelines/list/123123", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/timelines/list/123123", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -864,7 +1193,18 @@ exports[`Masto fetchLists 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/lists", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/lists", + }, ], ], "results": Array [ @@ -880,19 +1220,29 @@ exports[`Masto fetchMutes 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/mutes", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/mutes", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -902,7 +1252,18 @@ exports[`Masto fetchNotification 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/notifications/123123", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/notifications/123123", + }, ], ], "results": Array [ @@ -918,15 +1279,25 @@ exports[`Masto fetchNotifications 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/notifications", Object { - "exclude_types": Array [ - "favourite", - "follow", - "mention", - "poll", - "reblog", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "exclude_types": Array [ + "favourite", + "follow", + "mention", + "poll", + "reblog", + ], + }, + "transformResponse": Array [ + [Function], ], + "url": "https://example.com/api/v1/notifications", }, ], ], @@ -943,7 +1314,18 @@ exports[`Masto fetchPoll 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/polls/123123", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/polls/123123", + }, ], ], "results": Array [ @@ -959,7 +1341,18 @@ exports[`Masto fetchPreferences 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/preferences", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/preferences", + }, ], ], "results": Array [ @@ -975,19 +1368,29 @@ exports[`Masto fetchPublicTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/timelines/public", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/timelines/public", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -997,7 +1400,18 @@ exports[`Masto fetchPushSubscription 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/push/subscription", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/push/subscription", + }, ], ], "results": Array [ @@ -1013,7 +1427,18 @@ exports[`Masto fetchScheduledStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/scheduled_statuses/123123", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/scheduled_statuses/123123", + }, ], ], "results": Array [ @@ -1029,7 +1454,18 @@ exports[`Masto fetchScheduledStatuses 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/scheduled_statuses", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/scheduled_statuses", + }, ], ], "results": Array [ @@ -1045,7 +1481,18 @@ exports[`Masto fetchStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123", + }, ], ], "results": Array [ @@ -1061,7 +1508,18 @@ exports[`Masto fetchStatusCard 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/card", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/card", + }, ], ], "results": Array [ @@ -1077,7 +1535,18 @@ exports[`Masto fetchStatusContext 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/context", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/context", + }, ], ], "results": Array [ @@ -1093,19 +1562,29 @@ exports[`Masto fetchStatusFavouritedBy 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/favourited_by", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/favourited_by", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -1115,19 +1594,29 @@ exports[`Masto fetchStatusRebloggedBy 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/reblogged_by", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/reblogged_by", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -1137,7 +1626,18 @@ exports[`Masto fetchSuggestions 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/suggestions", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/suggestions", + }, ], ], "results": Array [ @@ -1153,19 +1653,29 @@ exports[`Masto fetchTagTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/timelines/tag/DeleteTwitter", Object { - "limit": 10, - "max_id": "5", - "min_id": "2", - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "limit": 10, + "max_id": "5", + "min_id": "2", + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/timelines/tag/DeleteTwitter", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -1175,9 +1685,16 @@ exports[`Masto followAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123/follow", Object { - "reblogs": false, + "data": "{\\"reblogs\\":false}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123/follow", }, ], ], @@ -1194,9 +1711,16 @@ exports[`Masto followAccountByUsername 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/follows", Object { - "uri": "user@example.com", + "data": "{\\"uri\\":\\"user@example.com\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/follows", }, ], ], @@ -1213,9 +1737,16 @@ exports[`Masto muteAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123/mute", Object { - "notifications": false, + "data": "{\\"notifications\\":false}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123/mute", }, ], ], @@ -1232,7 +1763,17 @@ exports[`Masto muteStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/mute", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/mute", + }, ], ], "results": Array [ @@ -1248,7 +1789,17 @@ exports[`Masto pinAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123/pin", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123/pin", + }, ], ], "results": Array [ @@ -1264,7 +1815,17 @@ exports[`Masto pinStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/pin", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/pin", + }, ], ], "results": Array [ @@ -1280,9 +1841,16 @@ exports[`Masto reblogStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/reblog", Object { - "visibility": "direct", + "data": "{\\"visibility\\":\\"direct\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/reblog", }, ], ], @@ -1299,7 +1867,17 @@ exports[`Masto rejectFollowRequest 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/follow_requests/123123/reject", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/follow_requests/123123/reject", + }, ], ], "results": Array [ @@ -1315,13 +1893,16 @@ exports[`Masto removeAccountFromList 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/lists/123123/accounts", Object { - "account_ids": Array [ - "123", - "456", - "678", + "data": "{\\"account_ids\\":[\\"123\\",\\"456\\",\\"678\\"]}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "DELETE", + "transformResponse": Array [ + [Function], ], + "url": "https://example.com/api/v1/lists/123123/accounts", }, ], ], @@ -1338,7 +1919,17 @@ exports[`Masto removeFilter 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/filters/123123", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "DELETE", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/filters/123123", + }, ], ], "results": Array [ @@ -1354,7 +1945,17 @@ exports[`Masto removeList 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/lists/123123", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "DELETE", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/lists/123123", + }, ], ], "results": Array [ @@ -1370,7 +1971,17 @@ exports[`Masto removePushSubscription 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/push/subscription", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "DELETE", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/push/subscription", + }, ], ], "results": Array [ @@ -1386,7 +1997,17 @@ exports[`Masto removeScheduledStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/scheduled_statuses/123123", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "DELETE", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/scheduled_statuses/123123", + }, ], ], "results": Array [ @@ -1402,7 +2023,17 @@ exports[`Masto removeStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "DELETE", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123", + }, ], ], "results": Array [ @@ -1418,7 +2049,17 @@ exports[`Masto removeSuggestion 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/suggestions/123123", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "DELETE", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/suggestions/123123", + }, ], ], "results": Array [ @@ -1434,14 +2075,16 @@ exports[`Masto reportAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/reports", Object { - "account_id": "123123", - "comment": "this is a report", - "forward": true, - "status_ids": Array [ - "456456", + "data": "{\\"account_id\\":\\"123123\\",\\"status_ids\\":[\\"456456\\"],\\"comment\\":\\"this is a report\\",\\"forward\\":true}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], ], + "url": "https://example.com/api/v1/reports", }, ], ], @@ -1458,10 +2101,16 @@ exports[`Masto revokeAccessToken 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/oauth/revoke", Object { - "client_id": "123123123", - "client_secret": "456456456", + "data": "{\\"client_id\\":\\"123123123\\",\\"client_secret\\":\\"456456456\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/oauth/revoke", }, ], ], @@ -1478,17 +2127,27 @@ exports[`Masto search (v1) 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/search", Object { - "q": "query", - "resolve": true, + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "q": "query", + "resolve": true, + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/search", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -1498,22 +2157,32 @@ exports[`Masto search 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v2/search", Object { - "account_id": "123", - "limit": 10, - "max_id": "5", - "min_id": "2", - "q": "query", - "resolve": true, - "since_id": "3", + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "account_id": "123", + "limit": 10, + "max_id": "5", + "min_id": "2", + "q": "query", + "resolve": true, + "since_id": "3", + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v2/search", }, ], ], "results": Array [ Object { "type": "return", - "value": undefined, + "value": Promise {}, }, ], } @@ -1523,12 +2192,22 @@ exports[`Masto searchAccounts 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/search", Object { - "following": false, - "limit": 123, - "q": "query", - "resolve": true, + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object { + "following": false, + "limit": 123, + "q": "query", + "resolve": true, + }, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/search", }, ], ], @@ -1545,16 +2224,14 @@ exports[`Masto streamCommunityTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/streaming", - Object { - "stream": "public:local", - }, + "wss://example.com/stream/api/v1/streaming?stream=public%3Alocal", + Array [], ], ], "results": Array [ Object { "type": "return", - "value": Promise {}, + "value": undefined, }, ], } @@ -1564,16 +2241,14 @@ exports[`Masto streamDirectTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/streaming", - Object { - "stream": "direct", - }, + "wss://example.com/stream/api/v1/streaming?stream=direct", + Array [], ], ], "results": Array [ Object { "type": "return", - "value": Promise {}, + "value": undefined, }, ], } @@ -1583,17 +2258,14 @@ exports[`Masto streamListTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/streaming", - Object { - "list": "123123", - "stream": "list", - }, + "wss://example.com/stream/api/v1/streaming?stream=list&list=123123", + Array [], ], ], "results": Array [ Object { "type": "return", - "value": Promise {}, + "value": undefined, }, ], } @@ -1603,17 +2275,14 @@ exports[`Masto streamLocalTagTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/streaming", - Object { - "stream": "hashtag:local", - "tag": "deletetwitter", - }, + "wss://example.com/stream/api/v1/streaming?stream=hashtag%3Alocal&tag=deletetwitter", + Array [], ], ], "results": Array [ Object { "type": "return", - "value": Promise {}, + "value": undefined, }, ], } @@ -1623,16 +2292,14 @@ exports[`Masto streamPublicTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/streaming", - Object { - "stream": "public", - }, + "wss://example.com/stream/api/v1/streaming?stream=public", + Array [], ], ], "results": Array [ Object { "type": "return", - "value": Promise {}, + "value": undefined, }, ], } @@ -1642,17 +2309,14 @@ exports[`Masto streamTagTimeline 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/streaming", - Object { - "stream": "hashtag", - "tag": "deletetwitter", - }, + "wss://example.com/stream/api/v1/streaming?stream=hashtag&tag=deletetwitter", + Array [], ], ], "results": Array [ Object { "type": "return", - "value": Promise {}, + "value": undefined, }, ], } @@ -1662,16 +2326,14 @@ exports[`Masto streamUser 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/streaming", - Object { - "stream": "user", - }, + "wss://example.com/stream/api/v1/streaming?stream=user", + Array [], ], ], "results": Array [ Object { "type": "return", - "value": Promise {}, + "value": undefined, }, ], } @@ -1681,7 +2343,17 @@ exports[`Masto unblockAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123/unblock", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123/unblock", + }, ], ], "results": Array [ @@ -1697,9 +2369,16 @@ exports[`Masto unblockDomain 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/domain_blocks", Object { - "domain": "example.com", + "data": "{\\"domain\\":\\"example.com\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "DELETE", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/domain_blocks", }, ], ], @@ -1716,7 +2395,17 @@ exports[`Masto unfavouriteStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/unfavourite", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/unfavourite", + }, ], ], "results": Array [ @@ -1732,7 +2421,17 @@ exports[`Masto unfollowAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123/unfollow", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123/unfollow", + }, ], ], "results": Array [ @@ -1748,7 +2447,17 @@ exports[`Masto unmuteAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123/unmute", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123/unmute", + }, ], ], "results": Array [ @@ -1764,7 +2473,17 @@ exports[`Masto unmuteStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/unmute", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/unmute", + }, ], ], "results": Array [ @@ -1780,7 +2499,17 @@ exports[`Masto unpinAccount 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/123123/unpin", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/123123/unpin", + }, ], ], "results": Array [ @@ -1796,7 +2525,17 @@ exports[`Masto unpinStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/unpin", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/unpin", + }, ], ], "results": Array [ @@ -1812,7 +2551,17 @@ exports[`Masto unreblogStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/statuses/123123/unreblog", + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/statuses/123123/unreblog", + }, ], ], "results": Array [ @@ -1828,29 +2577,61 @@ exports[`Masto updateCredentials 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/update_credentials", Object { - "avatar": "...", - "display_name": "Neetshin", - "fields_attributes": Array [ - Object { - "name": "GitHub", - "value": "https://github.com/neet", - }, - ], - "header": "...", - "locked": false, - "note": "web frontend engineer", - "source": Object { - "language": "ja", - "privacy": "direct", - "sensitive": false, + "data": FormData { + "_boundary": "--------------------------730168249685394248423831", + "_currentStream": null, + "_overheadLength": 529, + "_released": false, + "_streams": Array [ + "----------------------------730168249685394248423831 +Content-Disposition: form-data; name=\\"display_name\\" + +", + "Neetshin", + [Function], + "----------------------------730168249685394248423831 +Content-Disposition: form-data; name=\\"avatar\\" + +", + "...", + [Function], + "----------------------------730168249685394248423831 +Content-Disposition: form-data; name=\\"header\\" + +", + "...", + [Function], + "----------------------------730168249685394248423831 +Content-Disposition: form-data; name=\\"note\\" + +", + "web frontend engineer", + [Function], + "----------------------------730168249685394248423831 +Content-Disposition: form-data; name=\\"locked\\" + +", + false, + [Function], + ], + "_valueLength": 35, + "_valuesToMeasure": Array [], + "dataSize": 0, + "maxDataSize": 2097152, + "pauseStreams": true, + "readable": true, + "writable": false, }, - }, - Object { "headers": Object { "Content-Type": "multipart/form-data", + "content-type": "multipart/form-data; boundary=--------------------------730168249685394248423831", }, + "method": "PATCH", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/update_credentials", }, ], ], @@ -1867,18 +2648,16 @@ exports[`Masto updateFilter 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/filters/123123", Object { - "context": Array [ - "home", - "notifications", - "public", - "thread", + "data": "{\\"phrase\\":\\"Twitter\\",\\"context\\":[\\"home\\",\\"notifications\\",\\"public\\",\\"thread\\"],\\"irreversible\\":true,\\"whole_word\\":true,\\"expires_in\\":3600000}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "PUT", + "transformResponse": Array [ + [Function], ], - "expires_in": 3600000, - "irreversible": true, - "phrase": "Twitter", - "whole_word": true, + "url": "https://example.com/api/v1/filters/123123", }, ], ], @@ -1895,9 +2674,16 @@ exports[`Masto updateList 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/lists/123123", Object { - "title": "My list", + "data": "{\\"title\\":\\"My list\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "PUT", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/lists/123123", }, ], ], @@ -1914,10 +2700,16 @@ exports[`Masto updateMediaAttachment 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/media/123123", Object { - "description": "Nice image", - "focus": "0, 0", + "data": "{\\"description\\":\\"Nice image\\",\\"focus\\":\\"0, 0\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "PUT", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/media/123123", }, ], ], @@ -1934,16 +2726,16 @@ exports[`Masto updatePushSubscription 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/push/subscription", Object { - "data": Object { - "alerts": Object { - "favourite": true, - "follow": true, - "mention": true, - "reblog": true, - }, + "data": "{\\"data\\":{\\"alerts\\":{\\"follow\\":true,\\"favourite\\":true,\\"reblog\\":true,\\"mention\\":true}}}", + "headers": Object { + "Content-Type": "application/json", }, + "method": "PUT", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/push/subscription", }, ], ], @@ -1960,9 +2752,16 @@ exports[`Masto updateScheduledStatus 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/scheduled_statuses/123123", Object { - "scheduled_at": "2019-03-28T04:39:31.121Z", + "data": "{\\"scheduled_at\\":\\"2019-03-28T04:39:31.121Z\\"}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "PUT", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/scheduled_statuses/123123", }, ], ], @@ -1979,15 +2778,43 @@ exports[`Masto uploadMediaAttachment 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/media", - Object { - "description": "Nice image", - "file": "...", - }, Object { + "data": FormData { + "_boundary": "--------------------------607299666482247710728071", + "_currentStream": null, + "_overheadLength": 213, + "_released": false, + "_streams": Array [ + "----------------------------607299666482247710728071 +Content-Disposition: form-data; name=\\"file\\" + +", + "...", + [Function], + "----------------------------607299666482247710728071 +Content-Disposition: form-data; name=\\"description\\" + +", + "Nice image", + [Function], + ], + "_valueLength": 13, + "_valuesToMeasure": Array [], + "dataSize": 0, + "maxDataSize": 2097152, + "pauseStreams": true, + "readable": true, + "writable": false, + }, "headers": Object { "Content-Type": "multipart/form-data", + "content-type": "multipart/form-data; boundary=--------------------------607299666482247710728071", }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/media", }, ], ], @@ -2004,7 +2831,18 @@ exports[`Masto verifyAppCredentials 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/apps/verify_credentials", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/apps/verify_credentials", + }, ], ], "results": Array [ @@ -2020,7 +2858,18 @@ exports[`Masto verifyCredentials 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/accounts/verify_credentials", + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/accounts/verify_credentials", + }, ], ], "results": Array [ @@ -2036,13 +2885,16 @@ exports[`Masto votePoll 1`] = ` [MockFunction] { "calls": Array [ Array [ - "/api/v1/polls/123123/votes", Object { - "choices": Array [ - "xxx", - "yyy", - "zzz", + "data": "{\\"choices\\":[\\"xxx\\",\\"yyy\\",\\"zzz\\"]}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], ], + "url": "https://example.com/api/v1/polls/123123/votes", }, ], ], diff --git a/src/client/__tests__/masto.spec.ts b/src/client/__tests__/masto.spec.ts index 7a6e5843f..b8b8c1af8 100644 --- a/src/client/__tests__/masto.spec.ts +++ b/src/client/__tests__/masto.spec.ts @@ -1,30 +1,42 @@ // tslint:disable // @ts-ignore // prettier-ignore -import { getMock, postMock, deleteMock, patchMock, putMock, streamMock, paginateMock, Gateway } from '../../gateway/gateway'; +import axios from 'axios'; import { Masto } from '../masto'; +// @ts-ignore +import { WebSocketEvents, connectMock } from '../../gateway/ws-events'; -jest.mock('../../gateway/gateway'); +jest.mock('axios'); +jest.mock('../../gateway/ws-events'); describe('Masto', () => { // @ts-ignore - const masto = new Masto({ uri: 'https://example.com' }); + const masto = new Masto({ + uri: 'https://example.com', + version: '99.99.9', + streamingApiUrl: 'wss://example.com/stream', + }); beforeEach(() => { - (getMock as jest.Mock).mockClear(); - (postMock as jest.Mock).mockClear(); - (deleteMock as jest.Mock).mockClear(); - (patchMock as jest.Mock).mockClear(); - (putMock as jest.Mock).mockClear(); - (streamMock as jest.Mock).mockClear(); - (paginateMock as jest.Mock).mockClear(); + masto.version = '99.99.9'; // avoid version error + + (connectMock as jest.Mock).mockReset(); + (axios.request as jest.Mock).mockReset(); + (axios.request as jest.Mock).mockResolvedValue({ + headers: { + link: '; rel="next"', + }, + data: {}, + }); }); test('login', async () => { - (getMock as jest.Mock).mockResolvedValueOnce({ - version: '2.8.0', - urls: { - streaming_api: 'wss://example.com/stream', + (axios.request as jest.Mock).mockResolvedValueOnce({ + data: { + version: '2.8.0', + urls: { + streaming_api: 'wss://example.com/stream', + }, }, }); @@ -34,51 +46,50 @@ describe('Masto', () => { }; const masto = await Masto.login(params); - expect(getMock).toBeCalledWith(expect.stringContaining('/api/v1/instance')); expect(masto.version).toBe('2.8.0'); expect(masto.streamingApiUrl).toBe('wss://example.com/stream'); }); test('streamUser', async () => { await masto.streamUser(); - expect(streamMock).toBeCalledTimes(1); - expect(streamMock).toMatchSnapshot(); + expect(connectMock).toBeCalledTimes(1); + expect(connectMock).toMatchSnapshot(); }); test('streamPublicTimeline', async () => { await masto.streamPublicTimeline(); - expect(streamMock).toBeCalledTimes(1); - expect(streamMock).toMatchSnapshot(); + expect(connectMock).toBeCalledTimes(1); + expect(connectMock).toMatchSnapshot(); }); test('streamCommunityTimeline', async () => { await masto.streamCommunityTimeline(); - expect(streamMock).toBeCalledTimes(1); - expect(streamMock).toMatchSnapshot(); + expect(connectMock).toBeCalledTimes(1); + expect(connectMock).toMatchSnapshot(); }); test('streamTagTimeline', async () => { await masto.streamTagTimeline('deletetwitter'); - expect(streamMock).toBeCalledTimes(1); - expect(streamMock).toMatchSnapshot(); + expect(connectMock).toBeCalledTimes(1); + expect(connectMock).toMatchSnapshot(); }); test('streamLocalTagTimeline', async () => { await masto.streamLocalTagTimeline('deletetwitter'); - expect(streamMock).toBeCalledTimes(1); - expect(streamMock).toMatchSnapshot(); + expect(connectMock).toBeCalledTimes(1); + expect(connectMock).toMatchSnapshot(); }); test('streamListTimeline', async () => { await masto.streamListTimeline('123123'); - expect(streamMock).toBeCalledTimes(1); - expect(streamMock).toMatchSnapshot(); + expect(connectMock).toBeCalledTimes(1); + expect(connectMock).toMatchSnapshot(); }); test('streamDirectTimeline', async () => { await masto.streamDirectTimeline(); - expect(streamMock).toBeCalledTimes(1); - expect(streamMock).toMatchSnapshot(); + expect(connectMock).toBeCalledTimes(1); + expect(connectMock).toMatchSnapshot(); }); test('fetchAccessToken with authorization code', async () => { @@ -89,8 +100,8 @@ describe('Masto', () => { client_id: '123123123', client_secret: '456456456', }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchAccessToken with password', async () => { @@ -99,8 +110,8 @@ describe('Masto', () => { username: 'username', password: 'password', }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('revokeAccessToken', async () => { @@ -108,20 +119,20 @@ describe('Masto', () => { client_id: '123123123', client_secret: '456456456', }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchAccount', async () => { await masto.fetchAccount('123123123'); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchAccountIdentityProofs', async () => { await masto.fetchAccountIdentityProofs('123123123'); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('createAccount', async () => { @@ -131,14 +142,14 @@ describe('Masto', () => { email: 'example@example.com', agreement: true, }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('verifyCredentials', async () => { await masto.verifyCredentials(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('updateCredentials', async () => { @@ -148,73 +159,76 @@ describe('Masto', () => { header: '...', note: 'web frontend engineer', locked: false, - source: { - privacy: 'direct', - sensitive: false, - language: 'ja', - }, - fields_attributes: [ - { - name: 'GitHub', - value: 'https://github.com/neet', - }, - ], - }); - expect(patchMock).toBeCalledTimes(1); - expect(patchMock).toMatchSnapshot(); + // source: { + // privacy: 'direct', + // sensitive: false, + // language: 'ja', + // }, + // fields_attributes: [ + // { + // name: 'GitHub', + // value: 'https://github.com/neet', + // }, + // ], + }); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchAccountFollowers', async () => { - await masto.fetchAccountFollowers('123123123', { + const iterable = masto.fetchAccountFollowers('123123123', { max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchAccountFollowing', async () => { - await masto.fetchAccountFollowing('123123123', { + const iterable = masto.fetchAccountFollowing('123123123', { max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchAccountStatuses', async () => { - await masto.fetchAccountStatuses('123123123', { + const iterable = masto.fetchAccountStatuses('123123123', { max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('followAccount', async () => { await masto.followAccount('123123', { reblogs: false, }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('unfollowAccount', async () => { await masto.unfollowAccount('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchAccountRelationships', async () => { await masto.fetchAccountRelationships(['123123', '456456']); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('searchAccounts', async () => { @@ -224,8 +238,8 @@ describe('Masto', () => { limit: 123, following: false, }); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('createApp', async () => { @@ -235,118 +249,122 @@ describe('Masto', () => { scopes: 'write read', website: 'https://example.com', }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('verifyAppCredentials', async () => { await masto.verifyAppCredentials(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchBlocks', async () => { - await masto.fetchBlocks({ + const iterable = masto.fetchBlocks({ max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('blockAccount', async () => { await masto.blockAccount('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('unblockAccount', async () => { await masto.unblockAccount('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchCustomEmojis', async () => { await masto.fetchCustomEmojis(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchDomainBlocks', async () => { - await masto.fetchDomainBlocks(); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + const iterable = masto.fetchDomainBlocks(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('blockDomain', async () => { await masto.blockDomain('example.com'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('unblockDomain', async () => { await masto.unblockDomain('example.com'); - expect(deleteMock).toBeCalledTimes(1); - expect(deleteMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchEndorsements', async () => { - await masto.fetchEndorsements({ + const iterable = masto.fetchEndorsements({ max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('pinAccount', async () => { await masto.pinAccount('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('unpinAccount', async () => { await masto.unpinAccount('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchFavourites', async () => { - await masto.fetchFavourites({ + const iterable = masto.fetchFavourites({ max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('favouriteStatus', async () => { await masto.favouriteStatus('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('unfavouriteStatus', async () => { await masto.unfavouriteStatus('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchFilters', async () => { await masto.fetchFilters(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchFilter', async () => { await masto.fetchFilter('123123'); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('createFiler', async () => { @@ -357,8 +375,8 @@ describe('Masto', () => { whole_word: true, expires_in: 1000 * 60 * 60, }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('updateFilter', async () => { @@ -369,134 +387,136 @@ describe('Masto', () => { whole_word: true, expires_in: 1000 * 60 * 60, }); - expect(putMock).toBeCalledTimes(1); - expect(putMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('removeFilter', async () => { await masto.removeFilter('123123'); - expect(deleteMock).toBeCalledTimes(1); - expect(deleteMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchFollowRequests', async () => { - await masto.fetchFollowRequests({ + const iterable = masto.fetchFollowRequests({ max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('authorizeFollowRequest', async () => { await masto.authorizeFollowRequest('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('rejectFollowRequest', async () => { await masto.rejectFollowRequest('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchSuggestions', async () => { await masto.fetchSuggestions(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('removeSuggestion', async () => { await masto.removeSuggestion('123123'); - expect(deleteMock).toBeCalledTimes(1); - expect(deleteMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchInstance', async () => { await masto.fetchSuggestions(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchInstancesPeers', async () => { await masto.fetchInstancesPeers(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchInstanceActivity', async () => { await masto.fetchInstanceActivity(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchLists', async () => { await masto.fetchLists(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchAccountLists', async () => { await masto.fetchAccountLists('123123'); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchListAccounts', async () => { - await masto.fetchListAccounts('123123', { + const iterable = masto.fetchListAccounts('123123', { max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchList', async () => { await masto.fetchList('123123'); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('createList', async () => { await masto.createList({ title: 'My list', }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('updateList', async () => { await masto.updateList('123123', { title: 'My list', }); - expect(putMock).toBeCalledTimes(1); - expect(putMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('removeList', async () => { await masto.removeList('123123'); - expect(deleteMock).toBeCalledTimes(1); - expect(deleteMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('addAccountToList', async () => { await masto.addAccountToList('123123', { account_ids: ['123', '456', '678'], }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('removeAccountFromList', async () => { await masto.removeAccountFromList('123123', { account_ids: ['123', '456', '678'], }); - expect(deleteMock).toBeCalledTimes(1); - expect(deleteMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('uploadMediaAttachment', async () => { @@ -504,8 +524,8 @@ describe('Masto', () => { file: '...', description: 'Nice image', }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('updateMediaAttachment', async () => { @@ -513,71 +533,72 @@ describe('Masto', () => { description: 'Nice image', focus: '0, 0', }); - expect(putMock).toBeCalledTimes(1); - expect(putMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchMutes', async () => { - await masto.fetchMutes({ + const iterable = masto.fetchMutes({ max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('muteAccount', async () => { await masto.muteAccount('123123', { notifications: false, }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('unmuteAccount', async () => { await masto.unmuteAccount('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('muteStatus', async () => { await masto.muteStatus('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('unmuteStatus', async () => { await masto.unmuteStatus('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchNotifications', async () => { await masto.fetchNotifications({ exclude_types: ['favourite', 'follow', 'mention', 'poll', 'reblog'], }); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchNotification', async () => { await masto.fetchNotification('123123'); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('clearNotifications', async () => { await masto.clearNotifications(); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('dissmissNotification', async () => { await masto.dissmissNotification('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('addPushSubscription', async () => { @@ -595,14 +616,14 @@ describe('Masto', () => { }, }, }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchPushSubscription', async () => { await masto.fetchPushSubscription(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('updatePushSubscription', async () => { @@ -616,28 +637,28 @@ describe('Masto', () => { }, }, }); - expect(putMock).toBeCalledTimes(1); - expect(putMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('removePushSubscription', async () => { await masto.removePushSubscription(); - expect(deleteMock).toBeCalledTimes(1); - expect(deleteMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchPoll', async () => { await masto.fetchPoll('123123'); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('votePoll', async () => { await masto.votePoll('123123', { choices: ['xxx', 'yyy', 'zzz'], }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('reportAccount', async () => { @@ -647,50 +668,51 @@ describe('Masto', () => { comment: 'this is a report', forward: true, }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchScheduledStatuses', async () => { await masto.fetchScheduledStatuses(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchScheduledStatus', async () => { await masto.fetchScheduledStatus('123123'); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('updateScheduledStatus', async () => { await masto.updateScheduledStatus('123123', { scheduled_at: '2019-03-28T04:39:31.121Z', }); - expect(putMock).toBeCalledTimes(1); - expect(putMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('removeScheduledStatus', async () => { await masto.removeScheduledStatus('123123'); - expect(deleteMock).toBeCalledTimes(1); - expect(deleteMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('search (v1)', async () => { - await masto.search( + const iterable = masto.search( { q: 'query', resolve: true, }, 'v1', ); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('search', async () => { - await masto.search({ + const iterable = masto.search({ q: 'query', resolve: true, max_id: '5', @@ -699,48 +721,51 @@ describe('Masto', () => { limit: 10, account_id: '123', }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchStatus', async () => { await masto.fetchStatus('123123'); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchStatusContext', async () => { await masto.fetchStatusContext('123123'); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchStatusCard', async () => { await masto.fetchStatusCard('123123'); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchStatusRebloggedBy', async () => { - await masto.fetchStatusRebloggedBy('123123', { + const iterable = masto.fetchStatusRebloggedBy('123123', { max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchStatusFavouritedBy', async () => { - await masto.fetchStatusFavouritedBy('123123', { + const iterable = masto.fetchStatusFavouritedBy('123123', { max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('createStatus with content', async () => { @@ -759,16 +784,16 @@ describe('Masto', () => { scheduled_at: '2019-03-28T04:39:31.121Z', language: 'en', }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('createStatus with media ids', async () => { await masto.createStatus({ media_ids: ['123', '456'], }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('createStatus with Idempotency-Key', async () => { @@ -778,127 +803,134 @@ describe('Masto', () => { }, '59fe7e30-1a74-4050-8af7-5a8c7a224794', ); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('removeStatus', async () => { await masto.removeStatus('123123'); - expect(deleteMock).toBeCalledTimes(1); - expect(deleteMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('reblogStatus', async () => { await masto.reblogStatus('123123', { visibility: 'direct' }); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('unreblogStatus', async () => { await masto.unreblogStatus('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('pinStatus', async () => { await masto.pinStatus('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('unpinStatus', async () => { await masto.unpinStatus('123123'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchHomeTimeline', async () => { - await masto.fetchHomeTimeline({ + const iterable = masto.fetchHomeTimeline({ max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchCommunityTimeline', async () => { - await masto.fetchCommunityTimeline({ + const iterable = await masto.fetchCommunityTimeline({ max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchPublicTimeline', async () => { - await masto.fetchPublicTimeline({ + const iterable = await masto.fetchPublicTimeline({ max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchTagTimeline', async () => { - await masto.fetchTagTimeline('DeleteTwitter', { + const iterable = masto.fetchTagTimeline('DeleteTwitter', { max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchListTimeline', async () => { - await masto.fetchListTimeline('123123', { + const iterable = masto.fetchListTimeline('123123', { max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchDirectTimeline', async () => { masto.version = '2.5.0'; - await masto.fetchDirectTimeline({ + const iterable = masto.fetchDirectTimeline({ max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchConversations', async () => { - await masto.fetchConversations({ + const iterable = masto.fetchConversations({ max_id: '5', since_id: '3', min_id: '2', limit: 10, }); - expect(paginateMock).toBeCalledTimes(1); - expect(paginateMock).toMatchSnapshot(); + await iterable.next(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('followAccountByUsername', async () => { await masto.followAccountByUsername('user@example.com'); - expect(postMock).toBeCalledTimes(1); - expect(postMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); test('fetchPreferences', async () => { await masto.fetchPreferences(); - expect(getMock).toBeCalledTimes(1); - expect(getMock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); }); }); diff --git a/src/gateway/gateway.ts b/src/gateway/gateway.ts index f00b697a9..4c975ef39 100644 --- a/src/gateway/gateway.ts +++ b/src/gateway/gateway.ts @@ -372,7 +372,7 @@ export abstract class Gateway { ); // Set next url from the link header - const link = oc(response.headers.link)(''); + const link = oc(response.headers).link(''); const match = link.match(/<(.+?)>; rel="next"/) as string[]; currentUrl = (match && match.length && match[1]) || ''; From baa8c33624f7ec31d54140ae671511f834812771 Mon Sep 17 00:00:00 2001 From: Neetshin Date: Sat, 22 Jun 2019 18:50:43 +0900 Subject: [PATCH 04/10] implement moderation apis --- .../__tests__/decorators.spec.ts | 0 src/clients/client.ts | 3 + src/{client => clients}/decorators.ts | 6 +- src/clients/masto-admin/masto-admin.ts | 158 ++++++++++++++++++ src/clients/masto-admin/params.ts | 31 ++++ .../__snapshots__/masto.spec.ts.snap | 124 -------------- .../masto}/__tests__/masto.spec.ts | 17 +- src/{client => clients/masto}/masto.ts | 45 +++-- src/{client => clients/masto}/params.ts | 10 +- src/entities/admin-account.ts | 24 +++ src/entities/admin-report.ts | 14 ++ src/index.ts | 13 +- 12 files changed, 282 insertions(+), 163 deletions(-) rename src/{client => clients}/__tests__/decorators.spec.ts (100%) create mode 100644 src/clients/client.ts rename src/{client => clients}/decorators.ts (91%) create mode 100644 src/clients/masto-admin/masto-admin.ts create mode 100644 src/clients/masto-admin/params.ts rename src/{client => clients/masto}/__tests__/__snapshots__/masto.spec.ts.snap (94%) rename src/{client => clients/masto}/__tests__/masto.spec.ts (98%) rename src/{client => clients/masto}/masto.ts (97%) rename src/{client => clients/masto}/params.ts (96%) create mode 100644 src/entities/admin-account.ts create mode 100644 src/entities/admin-report.ts diff --git a/src/client/__tests__/decorators.spec.ts b/src/clients/__tests__/decorators.spec.ts similarity index 100% rename from src/client/__tests__/decorators.spec.ts rename to src/clients/__tests__/decorators.spec.ts diff --git a/src/clients/client.ts b/src/clients/client.ts new file mode 100644 index 000000000..d7c53889b --- /dev/null +++ b/src/clients/client.ts @@ -0,0 +1,3 @@ +import { GatewayConstructor } from '../gateway/gateway'; + +export type LoginParams = Pick; diff --git a/src/client/decorators.ts b/src/clients/decorators.ts similarity index 91% rename from src/client/decorators.ts rename to src/clients/decorators.ts index 106698ed0..5e111b955 100644 --- a/src/client/decorators.ts +++ b/src/clients/decorators.ts @@ -1,9 +1,9 @@ import semver from 'semver'; import { MastoNotFoundError } from '../errors/masto-not-found-error'; -import { Masto } from './masto'; +import { Gateway } from '../gateway/gateway'; export type Decorator = ( - masto: Masto, + gateway: Gateway, name: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => any>, ) => void; @@ -29,7 +29,7 @@ export const available = (parameters: AvailabeParams): Decorator => ( const original = descriptor.value; const { since, until } = parameters; - descriptor.value = function(this: Masto, ...args: any[]) { + descriptor.value = function(this: Gateway, ...args: any[]) { const version = semver.coerce(this.version); if (since && version && semver.lt(version, since)) { diff --git a/src/clients/masto-admin/masto-admin.ts b/src/clients/masto-admin/masto-admin.ts new file mode 100644 index 000000000..19e292970 --- /dev/null +++ b/src/clients/masto-admin/masto-admin.ts @@ -0,0 +1,158 @@ +import { AdminAccount } from '../../entities/admin-account'; +import { AdminReport } from '../../entities/admin-report'; +import { Gateway } from '../../gateway/gateway'; +import { available } from '../decorators'; +import { + AdminActionAccountParams, + AdminFetchAccountParams, + AdminFetchReportsParams, +} from './params'; + +/** + * Mastodon Moderation API client + */ +export class MastoAdmin extends Gateway { + /** + * Get accounts + * @param params parameters + * @retunr Accounts + */ + @available({ since: '2.9.1' }) + public fetchAccounts(params: AdminFetchAccountParams) { + return this.get('/api/v1/admin/accounts', params); + } + + /** + * Get a specific account + * @param id ID of the account + * @return Account + */ + @available({ since: '2.9.1' }) + public fetchAccount(id: string) { + return this.get(`/api/v1/admin/accounts/${id}`); + } + + /** + * Re-enable account + * @param id ID of the account + * @return Account + */ + @available({ since: '2.9.1' }) + public enableAccount(id: string) { + return this.post(`/api/v1/admin/accounts/${id}/enable`); + } + + /** + * Approve pending account + * @param id ID of the account + * @return Account + */ + @available({ since: '2.9.1' }) + public approveAccount(id: string) { + return this.post(`/api/v1/admin/accounts/${id}/approve`); + } + + /** + * Reject pending account + * @param id ID of the account + * @return Account + */ + @available({ since: '2.9.1' }) + public rejectAccount(id: string) { + return this.post(`/api/v1/admin/accounts/${id}/reject`); + } + + /** + * Unsilence account + * @param id ID of the account + * @return Account + */ + @available({ since: '2.9.1' }) + public unsilenceAccount(id: string) { + return this.post(`/api/v1/admin/accounts/${id}/unsilence`); + } + + /** + * Unsuspend account + * @param id ID of the account + * @return Account + */ + @available({ since: '2.9.1' }) + public unsuspendAccount(id: string) { + return this.post(`/api/v1/admin/accounts/${id}/unsuspend`); + } + + /** + * Get reports + * @param params params + * @return Reports + */ + @available({ since: '2.9.1' }) + public fetchReports(params: AdminFetchReportsParams) { + return this.get('/api/v1/admin/reports', params); + } + + /** + * Get a specific report + * @param id ID of the report + * @return Report + */ + @available({ since: '2.9.1' }) + public fetchReport(id: string) { + return this.get(`/api/v1/admin/reports/${id}`); + } + + /** + * Assign report to self + * @param id ID of the report + * @return Report + */ + @available({ since: '2.9.1' }) + public assignReportToSelf(id: string) { + return this.post(`/api/v1/admin/reports/${id}/assign_to_self`); + } + + /** + * Unassign report from self + * @param id ID of the report + * @return Report + */ + @available({ since: '2.9.1' }) + public unassignReport(id: string) { + return this.post(`/api/v1/admin/reports/${id}/unassign`); + } + + /** + * Re-open report + * @param id ID of the report + * @return Report + */ + @available({ since: '2.9.1' }) + public reopenReport(id: string) { + return this.post(`/api/v1/admin/reports/${id}/reopen`); + } + + /** + * Close report + * @param id ID of the report + * @return Report + */ + @available({ since: '2.9.1' }) + public resolveReport(id: string) { + return this.post(`/api/v1/admin/reports/${id}/resolve`); + } + + /** + * Perform a moderation action on an account + * @param id ID of the account + * @param params Params + * @return Acccount + */ + @available({ since: '2.9.1' }) + public actionAccount(id: string, params: AdminActionAccountParams) { + return this.post( + `/api/v1/admin/accounts/${id}/action`, + params, + ); + } +} diff --git a/src/clients/masto-admin/params.ts b/src/clients/masto-admin/params.ts new file mode 100644 index 000000000..506c73815 --- /dev/null +++ b/src/clients/masto-admin/params.ts @@ -0,0 +1,31 @@ +export interface AdminFetchAccountParams { + local?: boolean | null; + remote?: boolean | null; + by_domain?: string | null; + active?: boolean | null; + pending?: boolean | null; + disabled?: boolean | null; + silenced?: boolean | null; + suspended?: boolean | null; + usename?: string | null; + display_name?: string | null; + email?: string | null; + ip?: string | null; + staff?: boolean | null; +} + +export interface AdminFetchReportsParams { + resolved?: boolean | null; + account_id?: string | null; + target_account_id?: string | null; +} + +export type AccountActionType = 'none' | 'disable' | 'silence' | 'suspend'; + +export interface AdminActionAccountParams { + type: AccountActionType; + report_id: string; + warning_preset_id?: string | null; + text?: string | null; + send_email_notification?: boolean | null; +} diff --git a/src/client/__tests__/__snapshots__/masto.spec.ts.snap b/src/clients/masto/__tests__/__snapshots__/masto.spec.ts.snap similarity index 94% rename from src/client/__tests__/__snapshots__/masto.spec.ts.snap rename to src/clients/masto/__tests__/__snapshots__/masto.spec.ts.snap index 642592733..816f92ba7 100644 --- a/src/client/__tests__/__snapshots__/masto.spec.ts.snap +++ b/src/clients/masto/__tests__/__snapshots__/masto.spec.ts.snap @@ -2573,77 +2573,6 @@ exports[`Masto unreblogStatus 1`] = ` } `; -exports[`Masto updateCredentials 1`] = ` -[MockFunction] { - "calls": Array [ - Array [ - Object { - "data": FormData { - "_boundary": "--------------------------730168249685394248423831", - "_currentStream": null, - "_overheadLength": 529, - "_released": false, - "_streams": Array [ - "----------------------------730168249685394248423831 -Content-Disposition: form-data; name=\\"display_name\\" - -", - "Neetshin", - [Function], - "----------------------------730168249685394248423831 -Content-Disposition: form-data; name=\\"avatar\\" - -", - "...", - [Function], - "----------------------------730168249685394248423831 -Content-Disposition: form-data; name=\\"header\\" - -", - "...", - [Function], - "----------------------------730168249685394248423831 -Content-Disposition: form-data; name=\\"note\\" - -", - "web frontend engineer", - [Function], - "----------------------------730168249685394248423831 -Content-Disposition: form-data; name=\\"locked\\" - -", - false, - [Function], - ], - "_valueLength": 35, - "_valuesToMeasure": Array [], - "dataSize": 0, - "maxDataSize": 2097152, - "pauseStreams": true, - "readable": true, - "writable": false, - }, - "headers": Object { - "Content-Type": "multipart/form-data", - "content-type": "multipart/form-data; boundary=--------------------------730168249685394248423831", - }, - "method": "PATCH", - "transformResponse": Array [ - [Function], - ], - "url": "https://example.com/api/v1/accounts/update_credentials", - }, - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`; - exports[`Masto updateFilter 1`] = ` [MockFunction] { "calls": Array [ @@ -2774,59 +2703,6 @@ exports[`Masto updateScheduledStatus 1`] = ` } `; -exports[`Masto uploadMediaAttachment 1`] = ` -[MockFunction] { - "calls": Array [ - Array [ - Object { - "data": FormData { - "_boundary": "--------------------------607299666482247710728071", - "_currentStream": null, - "_overheadLength": 213, - "_released": false, - "_streams": Array [ - "----------------------------607299666482247710728071 -Content-Disposition: form-data; name=\\"file\\" - -", - "...", - [Function], - "----------------------------607299666482247710728071 -Content-Disposition: form-data; name=\\"description\\" - -", - "Nice image", - [Function], - ], - "_valueLength": 13, - "_valuesToMeasure": Array [], - "dataSize": 0, - "maxDataSize": 2097152, - "pauseStreams": true, - "readable": true, - "writable": false, - }, - "headers": Object { - "Content-Type": "multipart/form-data", - "content-type": "multipart/form-data; boundary=--------------------------607299666482247710728071", - }, - "method": "POST", - "transformResponse": Array [ - [Function], - ], - "url": "https://example.com/api/v1/media", - }, - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`; - exports[`Masto verifyAppCredentials 1`] = ` [MockFunction] { "calls": Array [ diff --git a/src/client/__tests__/masto.spec.ts b/src/clients/masto/__tests__/masto.spec.ts similarity index 98% rename from src/client/__tests__/masto.spec.ts rename to src/clients/masto/__tests__/masto.spec.ts index b8b8c1af8..f54915a55 100644 --- a/src/client/__tests__/masto.spec.ts +++ b/src/clients/masto/__tests__/masto.spec.ts @@ -3,11 +3,12 @@ // prettier-ignore import axios from 'axios'; import { Masto } from '../masto'; +import FormData from 'form-data'; // @ts-ignore -import { WebSocketEvents, connectMock } from '../../gateway/ws-events'; +import { WebSocketEvents, connectMock } from '../../../gateway/ws-events'; jest.mock('axios'); -jest.mock('../../gateway/ws-events'); +jest.mock('../../../gateway/ws-events'); describe('Masto', () => { // @ts-ignore @@ -172,7 +173,11 @@ describe('Masto', () => { // ], }); expect(axios.request as jest.Mock).toBeCalledTimes(1); - expect(axios.request as jest.Mock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledWith( + expect.objectContaining({ + data: expect.any(FormData), + }), + ); }); test('fetchAccountFollowers', async () => { @@ -525,7 +530,11 @@ describe('Masto', () => { description: 'Nice image', }); expect(axios.request as jest.Mock).toBeCalledTimes(1); - expect(axios.request as jest.Mock).toMatchSnapshot(); + expect(axios.request as jest.Mock).toBeCalledWith( + expect.objectContaining({ + data: expect.any(FormData), + }), + ); }); test('updateMediaAttachment', async () => { diff --git a/src/client/masto.ts b/src/clients/masto/masto.ts similarity index 97% rename from src/client/masto.ts rename to src/clients/masto/masto.ts index eec5575a0..c4a9dedd3 100644 --- a/src/client/masto.ts +++ b/src/clients/masto/masto.ts @@ -2,27 +2,28 @@ import { Account, AccountCredentials, AccountIdentityProof, -} from '../entities/account'; -import { Application } from '../entities/application'; -import { Attachment } from '../entities/attachment'; -import { Card } from '../entities/card'; -import { Context } from '../entities/context'; -import { Conversation } from '../entities/conversation'; -import { Emoji } from '../entities/emoji'; -import { Filter } from '../entities/filter'; -import { Instance, InstanceActivity } from '../entities/instance'; -import { List } from '../entities/list'; -import { Notification } from '../entities/notification'; -import { OAuthClient, OAuthToken } from '../entities/oauth'; -import { Poll } from '../entities/poll'; -import { Preference } from '../entities/preference'; -import { PushSubscription } from '../entities/push-subscription'; -import { Relationship } from '../entities/relationship'; -import { Results, ResultsV1 } from '../entities/results'; -import { ScheduledStatus } from '../entities/scheduled-status'; -import { Status } from '../entities/status'; -import { Gateway, GatewayConstructor } from '../gateway/gateway'; -import { available } from './decorators'; +} from '../../entities/account'; +import { Application } from '../../entities/application'; +import { Attachment } from '../../entities/attachment'; +import { Card } from '../../entities/card'; +import { Context } from '../../entities/context'; +import { Conversation } from '../../entities/conversation'; +import { Emoji } from '../../entities/emoji'; +import { Filter } from '../../entities/filter'; +import { Instance, InstanceActivity } from '../../entities/instance'; +import { List } from '../../entities/list'; +import { Notification } from '../../entities/notification'; +import { OAuthClient, OAuthToken } from '../../entities/oauth'; +import { Poll } from '../../entities/poll'; +import { Preference } from '../../entities/preference'; +import { PushSubscription } from '../../entities/push-subscription'; +import { Relationship } from '../../entities/relationship'; +import { Results, ResultsV1 } from '../../entities/results'; +import { ScheduledStatus } from '../../entities/scheduled-status'; +import { Status } from '../../entities/status'; +import { Gateway, GatewayConstructor } from '../../gateway/gateway'; +import { LoginParams } from '../client'; +import { available } from '../decorators'; import { AddPushSubscriptionParams, CreateAccountParams, @@ -51,8 +52,6 @@ import { VotePollParams, } from './params'; -export type LoginParams = Pick; - /** * Mastodon API client */ diff --git a/src/client/params.ts b/src/clients/masto/params.ts similarity index 96% rename from src/client/params.ts rename to src/clients/masto/params.ts index cfd2600ee..381d4909d 100644 --- a/src/client/params.ts +++ b/src/clients/masto/params.ts @@ -1,9 +1,9 @@ import { ReadStream } from 'fs'; -import { AccountField, AccountSource } from '../entities/account'; -import { FilterContext } from '../entities/filter'; -import { NotificationType } from '../entities/notification'; -import { PushSubscriptionAlerts } from '../entities/push-subscription'; -import { StatusVisibility } from '../entities/status'; +import { AccountField, AccountSource } from '../../entities/account'; +import { FilterContext } from '../../entities/filter'; +import { NotificationType } from '../../entities/notification'; +import { PushSubscriptionAlerts } from '../../entities/push-subscription'; +import { StatusVisibility } from '../../entities/status'; /** Union of acceptable values of form-data for browser and node */ export type IsomorphicFormDataValue = string | Blob | Buffer | ReadStream; diff --git a/src/entities/admin-account.ts b/src/entities/admin-account.ts new file mode 100644 index 000000000..a4aa080e9 --- /dev/null +++ b/src/entities/admin-account.ts @@ -0,0 +1,24 @@ +export type AdminAccountRole = 'moderator' | 'admin' | 'user'; + +/** + * Account entity from moderation apis + */ +export interface AdminAccount { + id: string; + username: string; + domain: string; + created_at: string; + email: string; + role: AdminAccountRole; + ip: string; + confirmed: boolean; + suspended: boolean; + silenced: boolean; + disabled: boolean; + approved: boolean; + account: Account; + locale?: string | null; + invite_request?: string | null; + created_by_application_id?: string | null; + invited_by_account_id?: string | null; +} diff --git a/src/entities/admin-report.ts b/src/entities/admin-report.ts new file mode 100644 index 000000000..8f73414e6 --- /dev/null +++ b/src/entities/admin-report.ts @@ -0,0 +1,14 @@ +import { Status } from './status'; + +export interface AdminReport { + id: string; + action_taken: boolean; + comment: string; + created_at: string; + updated_at: string; + account_id: string; + target_account_id: string; + assigned_account_id: string; + action_taken_by_account_id: string; + statuses: Status[]; +} diff --git a/src/index.ts b/src/index.ts index 09ec30874..52e588f25 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,15 @@ -export * from './client/decorators'; export * from './gateway/gateway'; -export * from './client/params'; export * from './gateway/ws-events'; export * from './gateway/utils'; +export * from './clients/decorators'; + +export * from './clients/masto/masto'; +export * from './clients/masto/params'; + +export * from './clients/masto-admin/masto-admin'; +export * from './clients/masto-admin/params'; + export * from './entities/account'; export * from './entities/application'; export * from './entities/attachment'; @@ -30,5 +36,4 @@ export * from './errors/masto-not-found-error'; export * from './errors/masto-rate-limit-error'; export * from './errors/masto-unauthorized-error'; -export * from './client/masto'; -export { Masto as default } from './client/masto'; +export { Masto as default } from './clients/masto/masto'; From 6e6fee2d87e930c082ce0c78bb6228a123854b08 Mon Sep 17 00:00:00 2001 From: Neetshin Date: Sat, 22 Jun 2019 19:29:10 +0900 Subject: [PATCH 05/10] Move #login to gateway --- src/clients/client.ts | 3 --- src/clients/masto/__tests__/masto.spec.ts | 20 ------------------ src/clients/masto/masto.ts | 20 ++---------------- src/gateway/__tests__/gateway.spec.ts | 21 ++++++++++++++++++- src/gateway/gateway.ts | 25 +++++++++++++++++++++-- 5 files changed, 45 insertions(+), 44 deletions(-) delete mode 100644 src/clients/client.ts diff --git a/src/clients/client.ts b/src/clients/client.ts deleted file mode 100644 index d7c53889b..000000000 --- a/src/clients/client.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { GatewayConstructor } from '../gateway/gateway'; - -export type LoginParams = Pick; diff --git a/src/clients/masto/__tests__/masto.spec.ts b/src/clients/masto/__tests__/masto.spec.ts index f54915a55..cdccb027d 100644 --- a/src/clients/masto/__tests__/masto.spec.ts +++ b/src/clients/masto/__tests__/masto.spec.ts @@ -31,26 +31,6 @@ describe('Masto', () => { }); }); - test('login', async () => { - (axios.request as jest.Mock).mockResolvedValueOnce({ - data: { - version: '2.8.0', - urls: { - streaming_api: 'wss://example.com/stream', - }, - }, - }); - - const params = { - uri: 'https://example.com', - accessToken: 'tokentoken', - }; - const masto = await Masto.login(params); - - expect(masto.version).toBe('2.8.0'); - expect(masto.streamingApiUrl).toBe('wss://example.com/stream'); - }); - test('streamUser', async () => { await masto.streamUser(); expect(connectMock).toBeCalledTimes(1); diff --git a/src/clients/masto/masto.ts b/src/clients/masto/masto.ts index c4a9dedd3..eaa458138 100644 --- a/src/clients/masto/masto.ts +++ b/src/clients/masto/masto.ts @@ -21,8 +21,7 @@ import { Relationship } from '../../entities/relationship'; import { Results, ResultsV1 } from '../../entities/results'; import { ScheduledStatus } from '../../entities/scheduled-status'; import { Status } from '../../entities/status'; -import { Gateway, GatewayConstructor } from '../../gateway/gateway'; -import { LoginParams } from '../client'; +import { Gateway, GatewayConstructorParams } from '../../gateway/gateway'; import { available } from '../decorators'; import { AddPushSubscriptionParams, @@ -56,25 +55,10 @@ import { * Mastodon API client */ export class Masto extends Gateway { - private constructor(params: GatewayConstructor) { + private constructor(params: GatewayConstructorParams) { super(params); } - /** - * Login to Mastodon - * @param params Paramters - * @return Instance of Mastodon class - */ - public static async login(params: LoginParams) { - const masto = new Masto(params); - const instance = await masto.fetchInstance(); - - masto.version = instance.version; - masto.streamingApiUrl = instance.urls.streaming_api; - - return masto; - } - /** * Starting home timeline and notification streaming * @return Instance of EventEmitter diff --git a/src/gateway/__tests__/gateway.spec.ts b/src/gateway/__tests__/gateway.spec.ts index 086383508..af993267f 100644 --- a/src/gateway/__tests__/gateway.spec.ts +++ b/src/gateway/__tests__/gateway.spec.ts @@ -1,6 +1,5 @@ // tslint:disable import axios from 'axios'; -import FormData from 'form-data'; // @ts-ignore import { Gateway, getMock } from '../gateway'; // @ts-ignore @@ -30,6 +29,26 @@ describe('Gateway', () => { }); }); + test('login', async () => { + (axios.request as jest.Mock).mockResolvedValueOnce({ + data: { + version: '2.8.0', + urls: { + streaming_api: 'wss://example.com/stream', + }, + }, + }); + + const params = { + uri: 'https://example.com', + accessToken: 'tokentoken', + }; + const gateway = await InheritedGateway.login(params); + + expect(gateway.version).toBe('2.8.0'); + expect(gateway.streamingApiUrl).toBe('wss://example.com/stream'); + }); + test('streamingApiUrl has been set if construct with streamingApiUrl', () => { gateway = new InheritedGateway({ uri: 'https://example.com', diff --git a/src/gateway/gateway.ts b/src/gateway/gateway.ts index 4c975ef39..814dc61be 100644 --- a/src/gateway/gateway.ts +++ b/src/gateway/gateway.ts @@ -3,6 +3,7 @@ import normalizeUrl from 'normalize-url'; import querystring from 'querystring'; import semver from 'semver'; import { oc } from 'ts-optchain'; +import { Instance } from '../entities/instance'; import { MastoNotFoundError } from '../errors/masto-not-found-error'; import { MastoRateLimitError } from '../errors/masto-rate-limit-error'; import { MastoUnauthorizedError } from '../errors/masto-unauthorized-error'; @@ -12,7 +13,7 @@ import { WebSocketEvents } from './ws-events'; // tslint:disable-next-line no-import-side-effect import 'isomorphic-form-data'; -export interface GatewayConstructor { +export interface GatewayConstructorParams { /** URI of the instance */ uri: string; /** Streaming API URL */ @@ -23,6 +24,8 @@ export interface GatewayConstructor { accessToken?: string; } +export type LoginParams = Pick; + export type PaginateNextOptions = { /** Reset pagination */ reset?: boolean; @@ -49,7 +52,7 @@ export abstract class Gateway { /** * @param params Parameters */ - public constructor(params: GatewayConstructor) { + constructor(params: GatewayConstructorParams) { this.uri = params.uri; if (params.streamingApiUrl) { @@ -81,6 +84,24 @@ export abstract class Gateway { this._streamingApiUrl = normalizeUrl(streamingApiUrl); } + /** + * Login to Mastodon + * @param params Paramters + * @return Instance of Mastodon class + */ + public static async login( + this: new (params: GatewayConstructorParams) => Gateway, + params: GatewayConstructorParams, + ) { + const masto = new this(params); + const instance = await masto.get('/api/v1/instance'); + + masto.version = instance.version; + masto.streamingApiUrl = instance.urls.streaming_api; + + return masto; + } + /** * Transform JSON to JS object * @param response Response object From 5d8b5f38a3f69e9b97025a4053c832fc044a07b3 Mon Sep 17 00:00:00 2001 From: Neetshin Date: Sun, 23 Jun 2019 01:51:32 +0900 Subject: [PATCH 06/10] Add unit tests for MastoAdmin --- .../__snapshots__/masto-admin.spec.ts.snap | 369 ++++++++++++++++++ .../masto-admin/__tests__/masto-admin.spec.ts | 117 ++++++ src/clients/masto-admin/masto-admin.ts | 4 +- src/clients/masto/__tests__/masto.spec.ts | 14 +- src/clients/masto/masto.ts | 6 +- src/gateway/gateway.ts | 19 +- 6 files changed, 505 insertions(+), 24 deletions(-) create mode 100644 src/clients/masto-admin/__tests__/__snapshots__/masto-admin.spec.ts.snap create mode 100644 src/clients/masto-admin/__tests__/masto-admin.spec.ts diff --git a/src/clients/masto-admin/__tests__/__snapshots__/masto-admin.spec.ts.snap b/src/clients/masto-admin/__tests__/__snapshots__/masto-admin.spec.ts.snap new file mode 100644 index 000000000..00dd13f6e --- /dev/null +++ b/src/clients/masto-admin/__tests__/__snapshots__/masto-admin.spec.ts.snap @@ -0,0 +1,369 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`MastoAdmin actionAccount 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": "{\\"type\\":\\"disable\\",\\"report_id\\":\\"123123\\",\\"warning_preset_id\\":\\"123123\\",\\"text\\":\\"Your account have been disabled\\",\\"send_email_notification\\":false}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/accounts/123/action", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin approveAccount 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/accounts/123/approve", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin assignReportToSelf 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/reports/123/assign_to_self", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin enableAccount 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/accounts/123/enable", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin fetchAccount 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/accounts/123", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin fetchAccounts 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/accounts", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin fetchReport 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/reports/123", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin fetchReports 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": undefined, + "headers": Object { + "Content-Type": "application/json", + }, + "method": "GET", + "params": Object {}, + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/reports", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin rejectAccount 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/accounts/123/reject", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin reopenReport 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/reports/123/reopen", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin resolveReport 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/reports/123/resolve", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin unassignReport 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/reports/123/unassign", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin unsilenceAccount 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/accounts/123/unsilence", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; + +exports[`MastoAdmin unsuspendAccount 1`] = ` +[MockFunction] { + "calls": Array [ + Array [ + Object { + "data": "{}", + "headers": Object { + "Content-Type": "application/json", + }, + "method": "POST", + "transformResponse": Array [ + [Function], + ], + "url": "https://example.com/api/v1/admin/accounts/123/unsuspend", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], +} +`; diff --git a/src/clients/masto-admin/__tests__/masto-admin.spec.ts b/src/clients/masto-admin/__tests__/masto-admin.spec.ts new file mode 100644 index 000000000..95ecc7b3c --- /dev/null +++ b/src/clients/masto-admin/__tests__/masto-admin.spec.ts @@ -0,0 +1,117 @@ +// @ts-ignore +import axios from 'axios'; +import { MastoAdmin } from '../masto-admin'; + +jest.mock('axios'); + +describe('MastoAdmin', () => { + const masto = new MastoAdmin({ + uri: 'https://example.com', + version: '99.99.9', + streamingApiUrl: 'wss://example.com/stream', + }); + + beforeAll(async () => { + (axios.request as jest.Mock).mockResolvedValue({ + headers: { + link: '; rel="next"', + }, + data: {}, + }); + }); + + beforeEach(async () => { + masto.version = '99.99.9'; // avoid version error + (axios.request as jest.Mock).mockClear(); + }); + + test('fetchAccounts', async () => { + await masto.fetchAccounts(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('fetchAccount', async () => { + await masto.fetchAccount('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('enableAccount', async () => { + await masto.enableAccount('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('approveAccount', async () => { + await masto.approveAccount('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('rejectAccount', async () => { + await masto.rejectAccount('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('unsilenceAccount', async () => { + await masto.unsilenceAccount('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('unsuspendAccount', async () => { + await masto.unsuspendAccount('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('fetchReports', async () => { + await masto.fetchReports(); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('fetchReport', async () => { + await masto.fetchReport('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('assignReportToSelf', async () => { + await masto.assignReportToSelf('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('unassignReport', async () => { + await masto.unassignReport('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('reopenReport', async () => { + await masto.reopenReport('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('resolveReport', async () => { + await masto.resolveReport('123'); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); + + test('actionAccount', async () => { + await masto.actionAccount('123', { + type: 'disable', + report_id: '123123', + warning_preset_id: '123123', + text: 'Your account have been disabled', + send_email_notification: false, + }); + expect(axios.request as jest.Mock).toBeCalledTimes(1); + expect(axios.request as jest.Mock).toMatchSnapshot(); + }); +}); diff --git a/src/clients/masto-admin/masto-admin.ts b/src/clients/masto-admin/masto-admin.ts index 19e292970..34cb92c62 100644 --- a/src/clients/masto-admin/masto-admin.ts +++ b/src/clients/masto-admin/masto-admin.ts @@ -18,7 +18,7 @@ export class MastoAdmin extends Gateway { * @retunr Accounts */ @available({ since: '2.9.1' }) - public fetchAccounts(params: AdminFetchAccountParams) { + public fetchAccounts(params?: AdminFetchAccountParams) { return this.get('/api/v1/admin/accounts', params); } @@ -88,7 +88,7 @@ export class MastoAdmin extends Gateway { * @return Reports */ @available({ since: '2.9.1' }) - public fetchReports(params: AdminFetchReportsParams) { + public fetchReports(params?: AdminFetchReportsParams) { return this.get('/api/v1/admin/reports', params); } diff --git a/src/clients/masto/__tests__/masto.spec.ts b/src/clients/masto/__tests__/masto.spec.ts index cdccb027d..dda46e72f 100644 --- a/src/clients/masto/__tests__/masto.spec.ts +++ b/src/clients/masto/__tests__/masto.spec.ts @@ -3,7 +3,6 @@ // prettier-ignore import axios from 'axios'; import { Masto } from '../masto'; -import FormData from 'form-data'; // @ts-ignore import { WebSocketEvents, connectMock } from '../../../gateway/ws-events'; @@ -11,18 +10,13 @@ jest.mock('axios'); jest.mock('../../../gateway/ws-events'); describe('Masto', () => { - // @ts-ignore const masto = new Masto({ uri: 'https://example.com', version: '99.99.9', streamingApiUrl: 'wss://example.com/stream', }); - beforeEach(() => { - masto.version = '99.99.9'; // avoid version error - - (connectMock as jest.Mock).mockReset(); - (axios.request as jest.Mock).mockReset(); + beforeAll(async () => { (axios.request as jest.Mock).mockResolvedValue({ headers: { link: '; rel="next"', @@ -31,6 +25,12 @@ describe('Masto', () => { }); }); + beforeEach(async () => { + masto.version = '99.99.9'; // avoid version error + (connectMock as jest.Mock).mockClear(); + (axios.request as jest.Mock).mockClear(); + }); + test('streamUser', async () => { await masto.streamUser(); expect(connectMock).toBeCalledTimes(1); diff --git a/src/clients/masto/masto.ts b/src/clients/masto/masto.ts index eaa458138..21f2e2c97 100644 --- a/src/clients/masto/masto.ts +++ b/src/clients/masto/masto.ts @@ -21,7 +21,7 @@ import { Relationship } from '../../entities/relationship'; import { Results, ResultsV1 } from '../../entities/results'; import { ScheduledStatus } from '../../entities/scheduled-status'; import { Status } from '../../entities/status'; -import { Gateway, GatewayConstructorParams } from '../../gateway/gateway'; +import { Gateway } from '../../gateway/gateway'; import { available } from '../decorators'; import { AddPushSubscriptionParams, @@ -55,10 +55,6 @@ import { * Mastodon API client */ export class Masto extends Gateway { - private constructor(params: GatewayConstructorParams) { - super(params); - } - /** * Starting home timeline and notification streaming * @return Instance of EventEmitter diff --git a/src/gateway/gateway.ts b/src/gateway/gateway.ts index 814dc61be..7fb978b3d 100644 --- a/src/gateway/gateway.ts +++ b/src/gateway/gateway.ts @@ -39,7 +39,7 @@ export type PaginateNextOptions = { * Mastodon network request wrapper * @param params Optional params */ -export abstract class Gateway { +export class Gateway { /** URI of the instance */ private _uri = ''; /** Streaming API URL of the instance */ @@ -89,17 +89,16 @@ export abstract class Gateway { * @param params Paramters * @return Instance of Mastodon class */ - public static async login( - this: new (params: GatewayConstructorParams) => Gateway, - params: GatewayConstructorParams, + public static async login( + this: T, + params: LoginParams, ) { - const masto = new this(params); - const instance = await masto.get('/api/v1/instance'); + const gateway = new this(params) as InstanceType; + const instance = await gateway.get('/api/v1/instance'); + gateway.version = instance.version; + gateway.streamingApiUrl = instance.urls.streaming_api; - masto.version = instance.version; - masto.streamingApiUrl = instance.urls.streaming_api; - - return masto; + return gateway; } /** From abccaaa9c6b55e131e2bc753f369a16558b6c427 Mon Sep 17 00:00:00 2001 From: Neetshin Date: Sun, 23 Jun 2019 01:56:22 +0900 Subject: [PATCH 07/10] Rename ws-events --- src/clients/masto/__tests__/masto.spec.ts | 4 ++-- src/gateway/__mocks__/{ws-events.ts => websocket.ts} | 0 src/gateway/__tests__/gateway.spec.ts | 4 ++-- src/gateway/__tests__/ws-events.spec.ts | 2 +- src/gateway/gateway.ts | 2 +- src/gateway/{ws-events.ts => websocket.ts} | 0 src/index.ts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) rename src/gateway/__mocks__/{ws-events.ts => websocket.ts} (100%) rename src/gateway/{ws-events.ts => websocket.ts} (100%) diff --git a/src/clients/masto/__tests__/masto.spec.ts b/src/clients/masto/__tests__/masto.spec.ts index dda46e72f..9426b54bb 100644 --- a/src/clients/masto/__tests__/masto.spec.ts +++ b/src/clients/masto/__tests__/masto.spec.ts @@ -4,10 +4,10 @@ import axios from 'axios'; import { Masto } from '../masto'; // @ts-ignore -import { WebSocketEvents, connectMock } from '../../../gateway/ws-events'; +import { WebSocketEvents, connectMock } from '../../../gateway/websocket'; jest.mock('axios'); -jest.mock('../../../gateway/ws-events'); +jest.mock('../../../gateway/websocket'); describe('Masto', () => { const masto = new Masto({ diff --git a/src/gateway/__mocks__/ws-events.ts b/src/gateway/__mocks__/websocket.ts similarity index 100% rename from src/gateway/__mocks__/ws-events.ts rename to src/gateway/__mocks__/websocket.ts diff --git a/src/gateway/__tests__/gateway.spec.ts b/src/gateway/__tests__/gateway.spec.ts index af993267f..9f7a3e2b6 100644 --- a/src/gateway/__tests__/gateway.spec.ts +++ b/src/gateway/__tests__/gateway.spec.ts @@ -3,13 +3,13 @@ import axios from 'axios'; // @ts-ignore import { Gateway, getMock } from '../gateway'; // @ts-ignore -import { WebSocketEvents, connectMock } from '../ws-events'; +import { WebSocketEvents, connectMock } from '../websocket'; import { MastoUnauthorizedError } from '../../errors/masto-unauthorized-error'; import { MastoNotFoundError } from '../../errors/masto-not-found-error'; import { MastoRateLimitError } from '../../errors/masto-rate-limit-error'; jest.mock('axios'); -jest.mock('../ws-events'); +jest.mock('../websocket'); describe('Gateway', () => { class InheritedGateway extends Gateway {} diff --git a/src/gateway/__tests__/ws-events.spec.ts b/src/gateway/__tests__/ws-events.spec.ts index 2198592e7..82d0d2db5 100644 --- a/src/gateway/__tests__/ws-events.spec.ts +++ b/src/gateway/__tests__/ws-events.spec.ts @@ -1,6 +1,6 @@ // tslint:disable import WebSocket from 'isomorphic-ws'; -import { WebSocketEvents } from '../ws-events'; +import { WebSocketEvents } from '../websocket'; const onMock = jest.fn(); const emitMock = jest.fn(); diff --git a/src/gateway/gateway.ts b/src/gateway/gateway.ts index 7fb978b3d..bb8314152 100644 --- a/src/gateway/gateway.ts +++ b/src/gateway/gateway.ts @@ -8,7 +8,7 @@ import { MastoNotFoundError } from '../errors/masto-not-found-error'; import { MastoRateLimitError } from '../errors/masto-rate-limit-error'; import { MastoUnauthorizedError } from '../errors/masto-unauthorized-error'; import { isAxiosError } from './utils'; -import { WebSocketEvents } from './ws-events'; +import { WebSocketEvents } from './websocket'; // tslint:disable-next-line no-import-side-effect import 'isomorphic-form-data'; diff --git a/src/gateway/ws-events.ts b/src/gateway/websocket.ts similarity index 100% rename from src/gateway/ws-events.ts rename to src/gateway/websocket.ts diff --git a/src/index.ts b/src/index.ts index 52e588f25..25a90fad9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ export * from './gateway/gateway'; -export * from './gateway/ws-events'; +export * from './gateway/websocket'; export * from './gateway/utils'; export * from './clients/decorators'; From c29ec1106bf1e6e68b656140db6ac35f3b310c18 Mon Sep 17 00:00:00 2001 From: Neetshin Date: Sun, 23 Jun 2019 01:57:15 +0900 Subject: [PATCH 08/10] Remove unused mock --- src/gateway/__mocks__/gateway.ts | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 src/gateway/__mocks__/gateway.ts diff --git a/src/gateway/__mocks__/gateway.ts b/src/gateway/__mocks__/gateway.ts deleted file mode 100644 index 28dd0f032..000000000 --- a/src/gateway/__mocks__/gateway.ts +++ /dev/null @@ -1,21 +0,0 @@ -export const getMock = jest.fn().mockResolvedValue({}); -export const postMock = jest.fn().mockResolvedValue({}); -export const deleteMock = jest.fn().mockResolvedValue({}); -export const patchMock = jest.fn().mockResolvedValue({}); -export const putMock = jest.fn().mockResolvedValue({}); -export const streamMock = jest.fn().mockResolvedValue({}); -export const paginateMock = jest.fn(); - -export const Gateway = jest.fn(() => ({ - uri: 'https://example.com', - streamingApiUrl: 'wss://example.com', - accessToken: 'token', - version: '99.99.9', - get: getMock, - post: postMock, - delete: deleteMock, - patch: patchMock, - put: putMock, - stream: streamMock, - paginate: paginateMock, -})); From 7f3871eea4c2d53c3431ad5feec73dea67d7e290 Mon Sep 17 00:00:00 2001 From: Neetshin Date: Sun, 23 Jun 2019 02:00:20 +0900 Subject: [PATCH 09/10] Fix typo --- src/clients/masto/__tests__/masto.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clients/masto/__tests__/masto.spec.ts b/src/clients/masto/__tests__/masto.spec.ts index 9426b54bb..09f88ac10 100644 --- a/src/clients/masto/__tests__/masto.spec.ts +++ b/src/clients/masto/__tests__/masto.spec.ts @@ -419,7 +419,7 @@ describe('Masto', () => { }); test('fetchInstance', async () => { - await masto.fetchSuggestions(); + await masto.fetchInstance(); expect(axios.request as jest.Mock).toBeCalledTimes(1); expect(axios.request as jest.Mock).toMatchSnapshot(); }); From e9016145904802f688c8221353430739f85717eb Mon Sep 17 00:00:00 2001 From: Neetshin Date: Sun, 23 Jun 2019 02:45:31 +0900 Subject: [PATCH 10/10] Improve websocket --- .../__snapshots__/masto.spec.ts.snap | 2 +- .../{ws-events.spec.ts => websocket.spec.ts} | 46 +++----- src/gateway/websocket.ts | 102 +++++++++++++----- 3 files changed, 94 insertions(+), 56 deletions(-) rename src/gateway/__tests__/{ws-events.spec.ts => websocket.spec.ts} (70%) diff --git a/src/clients/masto/__tests__/__snapshots__/masto.spec.ts.snap b/src/clients/masto/__tests__/__snapshots__/masto.spec.ts.snap index 816f92ba7..c816c4dba 100644 --- a/src/clients/masto/__tests__/__snapshots__/masto.spec.ts.snap +++ b/src/clients/masto/__tests__/__snapshots__/masto.spec.ts.snap @@ -1031,7 +1031,7 @@ exports[`Masto fetchInstance 1`] = ` "transformResponse": Array [ [Function], ], - "url": "https://example.com/api/v1/suggestions", + "url": "https://example.com/api/v1/instance", }, ], ], diff --git a/src/gateway/__tests__/ws-events.spec.ts b/src/gateway/__tests__/websocket.spec.ts similarity index 70% rename from src/gateway/__tests__/ws-events.spec.ts rename to src/gateway/__tests__/websocket.spec.ts index 82d0d2db5..64e74d76f 100644 --- a/src/gateway/__tests__/ws-events.spec.ts +++ b/src/gateway/__tests__/websocket.spec.ts @@ -3,9 +3,9 @@ import WebSocket from 'isomorphic-ws'; import { WebSocketEvents } from '../websocket'; const onMock = jest.fn(); +const onMockWs = jest.fn(); const emitMock = jest.fn(); const closeMock = jest.fn(); -const addEventListenerMock = jest.fn(); jest.mock('eventemitter3', () => { return class { @@ -17,7 +17,7 @@ jest.mock('eventemitter3', () => { jest.mock('isomorphic-ws', () => { return jest.fn(() => ({ close: closeMock, - addEventListener: addEventListenerMock, + on: onMockWs, })); }); @@ -28,9 +28,16 @@ describe('WebSocketEvents', () => { mastoEvents = new WebSocketEvents(); }); + beforeEach(() => { + onMock.mockClear(); + onMockWs.mockClear(); + emitMock.mockClear(); + closeMock.mockClear(); + }); + test('connect to ws server', async () => { // Resolve open - addEventListenerMock.mockImplementation((e, fn) => { + onMockWs.mockImplementation((e, fn) => { if (e === 'open') { fn(); } @@ -43,20 +50,9 @@ describe('WebSocketEvents', () => { [], ); - expect(addEventListenerMock).toHaveBeenCalledWith( - 'message', - expect.any(Function), - ); - - expect(addEventListenerMock).toHaveBeenCalledWith( - 'error', - expect.any(Function), - ); - - expect(addEventListenerMock).toHaveBeenCalledWith( - 'open', - expect.any(Function), - ); + expect(onMockWs).toBeCalledWith('message', expect.any(Function)); + expect(onMockWs).toBeCalledWith('error', expect.any(Function)); + expect(onMockWs).toBeCalledWith('open', expect.any(Function)); }); test('disconnect from the server', async () => { @@ -68,35 +64,23 @@ describe('WebSocketEvents', () => { const originalPayload = { aaaa: 'foobar', }; - const originalData = { event: 'update', payload: JSON.stringify(originalPayload), }; - mastoEvents.handleMessage({ - type: 'utf8', - data: JSON.stringify(originalData), - target: {} as any, - }); - + mastoEvents.handleMessage(JSON.stringify(originalData)); expect(emitMock).toBeCalledWith('update', originalPayload); }); test('emit event with given props, with raw payload', () => { const originalPayload = 'foobar'; - const originalData = { event: 'update', payload: originalPayload, }; - mastoEvents.handleMessage({ - type: 'utf8', - data: JSON.stringify(originalData), - target: {} as any, - }); - + mastoEvents.handleMessage(JSON.stringify(originalData)); expect(emitMock).toBeCalledWith('update', originalPayload); }); diff --git a/src/gateway/websocket.ts b/src/gateway/websocket.ts index 67e3349e2..9c3a32035 100644 --- a/src/gateway/websocket.ts +++ b/src/gateway/websocket.ts @@ -5,14 +5,13 @@ import { Conversation } from '../entities/conversation'; import { Notification } from '../entities/notification'; import { Status } from '../entities/status'; -/** Callback argument of `ws` */ -export interface Message { - data: string; - type: string; - target: WebSocket; +/** Mastodon event */ +export interface Event { + event: EventType; + payload: string; } -export interface EventTypesMap { +export interface EventTypeMap { /** Status posted */ update: Status; /** Status deleted */ @@ -25,7 +24,10 @@ export interface EventTypesMap { conversation: Conversation; } -export type EventTypes = keyof EventTypesMap; +export type EventType = keyof EventTypeMap; +export type EventListener = ( + payload: EventTypeMap[T], +) => void; /** * Mastodon streaming api wrapper @@ -43,9 +45,9 @@ export class WebSocketEvents extends EventEmitter { return new Promise((resolve, reject) => { this.ws = new WebSocket(url, protocols); - this.ws.addEventListener('message', this.handleMessage); - this.ws.addEventListener('error', reject); - this.ws.addEventListener('open', () => { + this.ws.on('message', this.handleMessage); + this.ws.on('error', reject); + this.ws.on('open', () => { resolve(this); }); }); @@ -63,31 +65,83 @@ export class WebSocketEvents extends EventEmitter { * Parse JSON data and emit it as an event * @param message Websocket message */ - public handleMessage = (message: Message) => { - const parsedMessage = JSON.parse(message.data); - let data: string | { [key: string]: any }; + public handleMessage = (message: string) => { + const event = JSON.parse(message) as Event; + let data: EventTypeMap[keyof EventTypeMap]; try { - data = JSON.parse(parsedMessage.payload); + data = JSON.parse(event.payload); } catch { // If parsing failed, returns raw data // Basically this is handling for `filters_changed` event // Which doesn't contain payload in the data - data = parsedMessage.payload; + data = event.payload; } - this.emit(parsedMessage.event, data); + this.emit(event.event, data); }; - /** - * Add listener for the event - * @param event Type of the event. One of `update`, `delete`, `notification`, `filters_changed`, `conversation` - * @param callback Callback function - */ - public on( + /*------------------------------- + * + * ↓ Overwriting signatures + * + *------------------------------*/ + + public listeners(event: T) { + return super.listeners(event); + } + + public listenerCount(event: T) { + return super.listenerCount(event); + } + + public emit(event: T, ...args: any[]) { + return super.emit(event, ...args); + } + + public addListener( event: T, - callback: (payload: EventTypesMap[T]) => void, + fn: EventListener, + context?: any, ) { - return super.on(event, callback); + return super.addListener(event, fn, context); + } + + public on( + event: T, + fn: EventListener, + context?: any, + ) { + return super.on(event, fn, context); + } + + public once( + event: T, + fn: EventListener, + context?: any, + ) { + return super.once(event, fn, context); + } + + public removeListener( + event: T, + fn?: EventListener, + context?: any, + once?: boolean, + ) { + return super.removeListener(event, fn, context, once); + } + + public off( + event: T, + fn?: EventListener, + context?: any, + once?: boolean, + ) { + return super.off(event, fn, context, once); + } + + public removeAllListeners(event?: T) { + return super.removeAllListeners(event); } }