Handle entry persisting state in actions and reducer + added tests.

This commit is contained in:
Andrey Okonetchnikov 2016-10-12 19:19:05 +02:00
parent a80d1087b2
commit 077e83dfc9
3 changed files with 84 additions and 16 deletions

View File

@ -83,8 +83,8 @@ export function entryPersisting(collection, entry) {
return {
type: ENTRY_PERSIST_REQUEST,
payload: {
collection,
entry,
collectionName: collection.get('name'),
entrySlug: entry.get('slug'),
},
};
}
@ -93,17 +93,21 @@ export function entryPersisted(collection, entry) {
return {
type: ENTRY_PERSIST_SUCCESS,
payload: {
collection,
entry,
collectionName: collection.get('name'),
entrySlug: entry.get('slug'),
},
};
}
export function entryPersistFail(collection, entry, error) {
return {
type: ENTRIES_FAILURE,
type: ENTRY_PERSIST_FAILURE,
error: 'Failed to persist entry',
payload: error.toString(),
payload: {
collectionName: collection.get('name'),
entrySlug: entry.get('slug'),
error: error.toString(),
},
};
}
@ -211,12 +215,10 @@ export function persistEntry(collection, entry) {
return (dispatch, getState) => {
const state = getState();
const backend = currentBackend(state.config);
const MediaProxies = entry.get('mediaFiles').map(path => getMedia(state, path));
const mediaProxies = entry.get('mediaFiles').map(path => getMedia(state, path));
dispatch(entryPersisting(collection, entry));
backend.persistEntry(state.config, collection, entry, MediaProxies.toJS()).then(
() => {
dispatch(entryPersisted(collection, entry));
},
backend.persistEntry(state.config, collection, entry, mediaProxies.toJS()).then(
() => dispatch(entryPersisted(collection, entry)),
error => dispatch(entryPersistFail(collection, entry, error))
);
};

View File

@ -1,15 +1,16 @@
import expect from 'expect';
import { Map, OrderedMap, fromJS } from 'immutable';
import { entriesLoading, entriesLoaded } from '../../actions/entries';
import Immutable, { Map, OrderedMap, fromJS } from 'immutable';
import * as actions from '../../actions/entries';
import reducer from '../entries';
let initialState;
describe('entries', () => {
it('should mark entries as fetching', () => {
const state = OrderedMap({
posts: Map({ name: 'posts' }),
});
expect(
reducer(state, entriesLoading(Map({ name: 'posts' })))
reducer(state, actions.entriesLoading(Map({ name: 'posts' })))
).toEqual(
OrderedMap(fromJS({
posts: { name: 'posts' },
@ -26,7 +27,7 @@ describe('entries', () => {
});
const entries = [{ slug: 'a', path: '' }, { slug: 'b', title: 'B' }];
expect(
reducer(state, entriesLoaded(Map({ name: 'posts' }), entries, 0))
reducer(state, actions.entriesLoaded(Map({ name: 'posts' }), entries, 0))
).toEqual(
OrderedMap(fromJS(
{
@ -45,4 +46,51 @@ describe('entries', () => {
))
);
});
describe('entry persisting', () => {
beforeEach(() => {
initialState = Immutable.fromJS({
entities: {
'posts.slug': {
collection: 'posts',
slug: 'slug',
path: 'content/blog/art-and-wine-festival.md',
partial: false,
raw: '',
data: {},
metaData: null,
},
},
pages: {},
});
});
it('should handle persisting request', () => {
const newState = reducer(
initialState,
actions.entryPersisting(Map({ name: 'posts' }), Map({ slug: 'slug' }))
);
expect(newState.getIn(['entities', 'posts.slug', 'isPersisting'])).toBe(true);
});
it('should handle persisting success', () => {
let newState = reducer(initialState,
actions.entryPersisting(Map({ name: 'posts' }), Map({ slug: 'slug' }))
);
newState = reducer(newState,
actions.entryPersisted(Map({ name: 'posts' }), Map({ slug: 'slug' }))
);
expect(newState.getIn(['entities', 'posts.slug', 'isPersisting'])).toBeUndefined();
});
it('should handle persisting error', () => {
let newState = reducer(initialState,
actions.entryPersisting(Map({ name: 'posts' }), Map({ slug: 'slug' }))
);
newState = reducer(newState,
actions.entryPersistFail(Map({ name: 'posts' }), Map({ slug: 'slug' }), 'Error message')
);
expect(newState.getIn(['entities', 'posts.slug', 'isPersisting'])).toBeUndefined();
});
});
});

View File

@ -2,6 +2,9 @@ import { Map, List, fromJS } from 'immutable';
import {
ENTRY_REQUEST,
ENTRY_SUCCESS,
ENTRY_PERSIST_REQUEST,
ENTRY_PERSIST_SUCCESS,
ENTRY_PERSIST_FAILURE,
ENTRIES_REQUEST,
ENTRIES_SUCCESS,
SEARCH_ENTRIES_REQUEST,
@ -13,6 +16,10 @@ let loadedEntries;
let page;
let searchTerm;
function getEntryPath(collectionName, entrySlug) {
return `${ collectionName }.${ entrySlug }`;
}
const entries = (state = Map({ entities: Map(), pages: Map() }), action) => {
switch (action.type) {
case ENTRY_REQUEST:
@ -24,6 +31,17 @@ const entries = (state = Map({ entities: Map(), pages: Map() }), action) => {
fromJS(action.payload.entry)
);
case ENTRY_PERSIST_REQUEST: {
const { collectionName, entrySlug } = action.payload;
return state.setIn(['entities', getEntryPath(collectionName, entrySlug), 'isPersisting'], true);
}
case ENTRY_PERSIST_SUCCESS:
case ENTRY_PERSIST_FAILURE: {
const { collectionName, entrySlug } = action.payload;
return state.deleteIn(['entities', getEntryPath(collectionName, entrySlug), 'isPersisting']);
}
case ENTRIES_REQUEST:
return state.setIn(['pages', action.payload.collection, 'isFetching'], true);