Convert blocks action to TypeScript

ci-review-rules
Justin 2022-05-26 13:37:22 -04:00
rodzic ff7753cb42
commit a335c06f13
5 zmienionych plików z 306 dodań i 96 usunięć

Wyświetl plik

@ -0,0 +1,8 @@
[
{
"id": "22",
"username": "twoods",
"acct": "twoods",
"display_name": "Tiger Woods"
}
]

Wyświetl plik

@ -1,6 +1,7 @@
import { jest } from '@jest/globals';
import { AxiosInstance } from 'axios';
import { AxiosInstance, AxiosResponse } from 'axios';
import MockAdapter from 'axios-mock-adapter';
import LinkHeader from 'http-link-header';
const api = jest.requireActual('../api') as Record<string, Function>;
let mocks: Array<Function> = [];
@ -15,6 +16,10 @@ const setupMock = (axios: AxiosInstance) => {
export const staticClient = api.staticClient;
export const getLinks = (response: AxiosResponse): LinkHeader => {
return new LinkHeader(response.headers?.link);
};
export const baseClient = (...params: any[]) => {
const axios = api.baseClient(...params);
setupMock(axios);

Wyświetl plik

@ -0,0 +1,183 @@
import { __stub } from 'soapbox/api';
import { mockStore } from 'soapbox/jest/test-helpers';
import rootReducer from 'soapbox/reducers';
import { expandBlocks, fetchBlocks } from '../blocks';
const account = {
acct: 'twoods',
display_name: 'Tiger Woods',
id: '22',
username: 'twoods',
};
describe('fetchBlocks()', () => {
let store;
describe('if logged out', () => {
beforeEach(() => {
const state = rootReducer(undefined, {}).set('me', null);
store = mockStore(state);
});
it('should do nothing', async() => {
await store.dispatch(fetchBlocks());
const actions = store.getActions();
expect(actions).toEqual([]);
});
});
describe('if logged in', () => {
beforeEach(() => {
const state = rootReducer(undefined, {}).set('me', '1234');
store = mockStore(state);
});
describe('with a successful API request', () => {
beforeEach(() => {
const blocks = require('soapbox/__fixtures__/blocks.json');
__stub((mock) => {
mock.onGet('/api/v1/blocks').reply(200, blocks, {
link: '<https://example.com/api/v1/blocks?since_id=1>; rel=\'prev\'',
});
});
});
it('should fetch blocks from the API', async() => {
const expectedActions = [
{ type: 'BLOCKS_FETCH_REQUEST' },
{ type: 'ACCOUNTS_IMPORT', accounts: [account] },
{ type: 'BLOCKS_FETCH_SUCCESS', accounts: [account], next: null },
{
type: 'RELATIONSHIPS_FETCH_REQUEST',
ids: ['22'],
skipLoading: true,
},
];
await store.dispatch(fetchBlocks());
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
describe('with an unsuccessful API request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet('/api/v1/blocks').networkError();
});
});
it('should dispatch failed action', async() => {
const expectedActions = [
{ type: 'BLOCKS_FETCH_REQUEST' },
{ type: 'BLOCKS_FETCH_FAIL', error: new Error('Network Error') },
];
await store.dispatch(fetchBlocks());
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
});
});
describe('expandBlocks()', () => {
let store;
describe('if logged out', () => {
beforeEach(() => {
const state = rootReducer(undefined, {}).set('me', null);
store = mockStore(state);
});
it('should do nothing', async() => {
await store.dispatch(expandBlocks());
const actions = store.getActions();
expect(actions).toEqual([]);
});
});
describe('if logged in', () => {
beforeEach(() => {
const state = rootReducer(undefined, {}).set('me', '1234');
store = mockStore(state);
});
describe('without a url', () => {
beforeEach(() => {
const state = rootReducer(undefined, {})
.set('me', '1234')
.set('user_lists', { blocks: { next: null } });
store = mockStore(state);
});
it('should do nothing', async() => {
await store.dispatch(expandBlocks());
const actions = store.getActions();
expect(actions).toEqual([]);
});
});
describe('with a url', () => {
beforeEach(() => {
const state = rootReducer(undefined, {})
.set('me', '1234')
.set('user_lists', { blocks: { next: 'example' } });
store = mockStore(state);
});
describe('with a successful API request', () => {
beforeEach(() => {
const blocks = require('soapbox/__fixtures__/blocks.json');
__stub((mock) => {
mock.onGet('example').reply(200, blocks, {
link: '<https://example.com/api/v1/blocks?since_id=1>; rel=\'prev\'',
});
});
});
it('should fetch blocks from the url', async() => {
const expectedActions = [
{ type: 'BLOCKS_EXPAND_REQUEST' },
{ type: 'ACCOUNTS_IMPORT', accounts: [account] },
{ type: 'BLOCKS_EXPAND_SUCCESS', accounts: [account], next: null },
{
type: 'RELATIONSHIPS_FETCH_REQUEST',
ids: ['22'],
skipLoading: true,
},
];
await store.dispatch(expandBlocks());
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
describe('with an unsuccessful API request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet('example').networkError();
});
});
it('should dispatch failed action', async() => {
const expectedActions = [
{ type: 'BLOCKS_EXPAND_REQUEST' },
{ type: 'BLOCKS_EXPAND_FAIL', error: new Error('Network Error') },
];
await store.dispatch(expandBlocks());
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
});
});
});

Wyświetl plik

@ -1,95 +0,0 @@
import { isLoggedIn } from 'soapbox/utils/auth';
import { getNextLinkName } from 'soapbox/utils/quirks';
import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts } from './importer';
export const BLOCKS_FETCH_REQUEST = 'BLOCKS_FETCH_REQUEST';
export const BLOCKS_FETCH_SUCCESS = 'BLOCKS_FETCH_SUCCESS';
export const BLOCKS_FETCH_FAIL = 'BLOCKS_FETCH_FAIL';
export const BLOCKS_EXPAND_REQUEST = 'BLOCKS_EXPAND_REQUEST';
export const BLOCKS_EXPAND_SUCCESS = 'BLOCKS_EXPAND_SUCCESS';
export const BLOCKS_EXPAND_FAIL = 'BLOCKS_EXPAND_FAIL';
export function fetchBlocks() {
return (dispatch, getState) => {
if (!isLoggedIn(getState)) return;
const nextLinkName = getNextLinkName(getState);
dispatch(fetchBlocksRequest());
api(getState).get('/api/v1/blocks').then(response => {
const next = getLinks(response).refs.find(link => link.rel === nextLinkName);
dispatch(importFetchedAccounts(response.data));
dispatch(fetchBlocksSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(fetchBlocksFail(error)));
};
}
export function fetchBlocksRequest() {
return {
type: BLOCKS_FETCH_REQUEST,
};
}
export function fetchBlocksSuccess(accounts, next) {
return {
type: BLOCKS_FETCH_SUCCESS,
accounts,
next,
};
}
export function fetchBlocksFail(error) {
return {
type: BLOCKS_FETCH_FAIL,
error,
};
}
export function expandBlocks() {
return (dispatch, getState) => {
if (!isLoggedIn(getState)) return;
const nextLinkName = getNextLinkName(getState);
const url = getState().getIn(['user_lists', 'blocks', 'next']);
if (url === null) {
return;
}
dispatch(expandBlocksRequest());
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === nextLinkName);
dispatch(importFetchedAccounts(response.data));
dispatch(expandBlocksSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(expandBlocksFail(error)));
};
}
export function expandBlocksRequest() {
return {
type: BLOCKS_EXPAND_REQUEST,
};
}
export function expandBlocksSuccess(accounts, next) {
return {
type: BLOCKS_EXPAND_SUCCESS,
accounts,
next,
};
}
export function expandBlocksFail(error) {
return {
type: BLOCKS_EXPAND_FAIL,
error,
};
}

Wyświetl plik

@ -0,0 +1,109 @@
import { AnyAction } from '@reduxjs/toolkit';
import { AxiosError } from 'axios';
import { isLoggedIn } from 'soapbox/utils/auth';
import { getNextLinkName } from 'soapbox/utils/quirks';
import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts } from './importer';
const BLOCKS_FETCH_REQUEST = 'BLOCKS_FETCH_REQUEST';
const BLOCKS_FETCH_SUCCESS = 'BLOCKS_FETCH_SUCCESS';
const BLOCKS_FETCH_FAIL = 'BLOCKS_FETCH_FAIL';
const BLOCKS_EXPAND_REQUEST = 'BLOCKS_EXPAND_REQUEST';
const BLOCKS_EXPAND_SUCCESS = 'BLOCKS_EXPAND_SUCCESS';
const BLOCKS_EXPAND_FAIL = 'BLOCKS_EXPAND_FAIL';
const fetchBlocks = () => (dispatch: React.Dispatch<AnyAction>, getState: any) => {
if (!isLoggedIn(getState)) return null;
const nextLinkName = getNextLinkName(getState);
dispatch(fetchBlocksRequest());
return api(getState)
.get('/api/v1/blocks')
.then(response => {
const next = getLinks(response).refs.find(link => link.rel === nextLinkName);
dispatch(importFetchedAccounts(response.data));
dispatch(fetchBlocksSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map((item: any) => item.id)) as any);
})
.catch(error => dispatch(fetchBlocksFail(error)));
};
function fetchBlocksRequest() {
return { type: BLOCKS_FETCH_REQUEST };
}
function fetchBlocksSuccess(accounts: any, next: any) {
return {
type: BLOCKS_FETCH_SUCCESS,
accounts,
next,
};
}
function fetchBlocksFail(error: AxiosError) {
return {
type: BLOCKS_FETCH_FAIL,
error,
};
}
const expandBlocks = () => (dispatch: React.Dispatch<AnyAction>, getState: any) => {
if (!isLoggedIn(getState)) return null;
const nextLinkName = getNextLinkName(getState);
const url = getState().getIn(['user_lists', 'blocks', 'next']);
if (url === null) {
return null;
}
dispatch(expandBlocksRequest());
return api(getState)
.get(url)
.then(response => {
const next = getLinks(response).refs.find(link => link.rel === nextLinkName);
dispatch(importFetchedAccounts(response.data));
dispatch(expandBlocksSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map((item: any) => item.id)) as any);
})
.catch(error => dispatch(expandBlocksFail(error)));
};
function expandBlocksRequest() {
return {
type: BLOCKS_EXPAND_REQUEST,
};
}
function expandBlocksSuccess(accounts: any, next: any) {
return {
type: BLOCKS_EXPAND_SUCCESS,
accounts,
next,
};
}
function expandBlocksFail(error: AxiosError) {
return {
type: BLOCKS_EXPAND_FAIL,
error,
};
}
export {
fetchBlocks,
expandBlocks,
BLOCKS_FETCH_REQUEST,
BLOCKS_FETCH_SUCCESS,
BLOCKS_FETCH_FAIL,
BLOCKS_EXPAND_REQUEST,
BLOCKS_EXPAND_SUCCESS,
BLOCKS_EXPAND_FAIL,
};