sforkowany z mirror/soapbox
Add "carousel" redux logic
rodzic
2a7fd15717
commit
33bebf5bba
|
@ -0,0 +1,58 @@
|
|||
import { __stub } from 'soapbox/api';
|
||||
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
|
||||
|
||||
import { fetchCarouselAvatars } from '../carousels';
|
||||
|
||||
describe('fetchCarouselAvatars()', () => {
|
||||
let store;
|
||||
|
||||
beforeEach(() => {
|
||||
store = mockStore(rootState);
|
||||
});
|
||||
|
||||
describe('with a successful API request', () => {
|
||||
let avatars;
|
||||
|
||||
beforeEach(() => {
|
||||
avatars = [
|
||||
{ account_id: '1', username: 'jl', account_avatar: 'https://example.com/some.jpg' },
|
||||
];
|
||||
|
||||
__stub((mock) => {
|
||||
mock.onGet('/api/v1/truth/carousels/avatars').reply(200, avatars);
|
||||
});
|
||||
});
|
||||
|
||||
it('should fetch the users from the API', async() => {
|
||||
const expectedActions = [
|
||||
{ type: 'CAROUSEL_AVATAR_REQUEST' },
|
||||
{ type: 'CAROUSEL_AVATAR_SUCCESS', payload: avatars },
|
||||
];
|
||||
|
||||
await store.dispatch(fetchCarouselAvatars());
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toEqual(expectedActions);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with an unsuccessful API request', () => {
|
||||
beforeEach(() => {
|
||||
__stub((mock) => {
|
||||
mock.onGet('/api/v1/truth/carousels/avatars').networkError();
|
||||
});
|
||||
});
|
||||
|
||||
it('should dispatch failed action', async() => {
|
||||
const expectedActions = [
|
||||
{ type: 'CAROUSEL_AVATAR_REQUEST' },
|
||||
{ type: 'CAROUSEL_AVATAR_FAIL' },
|
||||
];
|
||||
|
||||
await store.dispatch(fetchCarouselAvatars());
|
||||
const actions = store.getActions();
|
||||
|
||||
expect(actions).toEqual(expectedActions);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
import { AxiosResponse } from 'axios';
|
||||
|
||||
import { AppDispatch, RootState } from 'soapbox/store';
|
||||
|
||||
import api from '../api';
|
||||
|
||||
const CAROUSEL_AVATAR_REQUEST = 'CAROUSEL_AVATAR_REQUEST';
|
||||
const CAROUSEL_AVATAR_SUCCESS = 'CAROUSEL_AVATAR_SUCCESS';
|
||||
const CAROUSEL_AVATAR_FAIL = 'CAROUSEL_AVATAR_FAIL';
|
||||
|
||||
const fetchCarouselAvatars = () => (dispatch: AppDispatch, getState: () => RootState) => {
|
||||
dispatch({ type: CAROUSEL_AVATAR_REQUEST });
|
||||
|
||||
return api(getState)
|
||||
.get('/api/v1/truth/carousels/avatars')
|
||||
.then((response: AxiosResponse) => dispatch({ type: CAROUSEL_AVATAR_SUCCESS, payload: response.data }))
|
||||
.catch(() => dispatch({ type: CAROUSEL_AVATAR_FAIL }));
|
||||
};
|
||||
|
||||
export {
|
||||
CAROUSEL_AVATAR_REQUEST,
|
||||
CAROUSEL_AVATAR_SUCCESS,
|
||||
CAROUSEL_AVATAR_FAIL,
|
||||
fetchCarouselAvatars,
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
import { AnyAction } from 'redux';
|
||||
|
||||
import {
|
||||
CAROUSEL_AVATAR_REQUEST,
|
||||
CAROUSEL_AVATAR_SUCCESS,
|
||||
CAROUSEL_AVATAR_FAIL,
|
||||
} from 'soapbox/actions/carousels';
|
||||
|
||||
import reducer from '../carousels';
|
||||
|
||||
describe('carousels reducer', () => {
|
||||
it('should return the initial state', () => {
|
||||
expect(reducer(undefined, {} as AnyAction)).toEqual({
|
||||
avatars: [],
|
||||
isLoading: false,
|
||||
});
|
||||
});
|
||||
|
||||
describe('CAROUSEL_AVATAR_REQUEST', () => {
|
||||
it('sets "isLoading" to "true"', () => {
|
||||
const initialState = { isLoading: false, avatars: [] };
|
||||
const action = { type: CAROUSEL_AVATAR_REQUEST };
|
||||
expect(reducer(initialState, action).isLoading).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CAROUSEL_AVATAR_SUCCESS', () => {
|
||||
it('sets the next state', () => {
|
||||
const initialState = { isLoading: true, avatars: [] };
|
||||
const action = { type: CAROUSEL_AVATAR_SUCCESS, payload: [45] };
|
||||
const result = reducer(initialState, action);
|
||||
|
||||
expect(result.isLoading).toEqual(false);
|
||||
expect(result.avatars).toEqual([45]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CAROUSEL_AVATAR_FAIL', () => {
|
||||
it('sets "isLoading" to "true"', () => {
|
||||
const initialState = { isLoading: true, avatars: [] };
|
||||
const action = { type: CAROUSEL_AVATAR_FAIL };
|
||||
expect(reducer(initialState, action).isLoading).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
import { AnyAction } from 'redux';
|
||||
|
||||
import {
|
||||
CAROUSEL_AVATAR_REQUEST,
|
||||
CAROUSEL_AVATAR_SUCCESS,
|
||||
CAROUSEL_AVATAR_FAIL,
|
||||
} from '../actions/carousels';
|
||||
|
||||
type Avatar = {
|
||||
account_id: string
|
||||
account_avatar: string
|
||||
username: string
|
||||
}
|
||||
|
||||
type CarouselsState = {
|
||||
avatars: Avatar[],
|
||||
isLoading: boolean
|
||||
}
|
||||
|
||||
const initialState: CarouselsState = {
|
||||
avatars: [],
|
||||
isLoading: false,
|
||||
};
|
||||
|
||||
export default function rules(state: CarouselsState = initialState, action: AnyAction): CarouselsState {
|
||||
switch (action.type) {
|
||||
case CAROUSEL_AVATAR_REQUEST:
|
||||
return { ...state, isLoading: true };
|
||||
case CAROUSEL_AVATAR_SUCCESS:
|
||||
return { ...state, isLoading: false, avatars: action.payload };
|
||||
case CAROUSEL_AVATAR_FAIL:
|
||||
return { ...state, isLoading: false };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ import alerts from './alerts';
|
|||
import aliases from './aliases';
|
||||
import auth from './auth';
|
||||
import backups from './backups';
|
||||
import carousels from './carousels';
|
||||
import chat_message_lists from './chat_message_lists';
|
||||
import chat_messages from './chat_messages';
|
||||
import chats from './chats';
|
||||
|
@ -122,6 +123,7 @@ const reducers = {
|
|||
onboarding,
|
||||
rules,
|
||||
history,
|
||||
carousels,
|
||||
};
|
||||
|
||||
// Build a default state from all reducers: it has the key and `undefined`
|
||||
|
|
Ładowanie…
Reference in New Issue