Browse Source

Add reducer and tests.

Snow 8 years ago
parent
commit
3ed0c9363b
3 changed files with 92 additions and 8 deletions
  1. 37 0
      src/__test__/reducers.test.js
  2. 7 7
      src/actions/index.js
  3. 48 1
      src/reducers/index.js

+ 37 - 0
src/__test__/reducers.test.js

@@ -0,0 +1,37 @@
+import reducer from '../reducers';
+import actions from '../actions';
+
+describe('Select works', () => {
+  it('Default state is set', () => {
+    expect(reducer(undefined, {}).selectedSubreddit).toBe('reactjs');
+  });
+  it('Selected reddit should change on new selections', () => {
+    const testReddit = 'Darksouls';
+    const action = actions.selectSubreddit(testReddit);
+    const newState = reducer(undefined, action);
+    expect(newState.selectedSubreddit).toEqual(testReddit);
+  });
+});
+
+describe('Request works', () => {
+  it('Default post state is empty', () => {
+    const testReddit = 'Darksouls';
+    const defaultState = reducer(undefined, []).postsBySubreddit;
+    expect(defaultState).toEqual({});
+  });
+  it('Request a subreddit should change isFetching status to true', () => {
+    const testReddit = 'Darksouls';
+    const action = actions.requestPost(testReddit);
+    const result = {
+      [testReddit]: {
+        isFetching: true,
+        didInvalidate: false,
+        items: []
+      }
+    };
+    const posts = reducer(undefined, action).postsBySubreddit;
+    expect(posts).toEqual(result);
+    const isFetching = posts[testReddit].isFetching;
+    expect(isFetching).toBeTrue;
+  });
+});

+ 7 - 7
src/actions/index.js

@@ -1,17 +1,17 @@
 import { createActions } from 'redux-actions';
-import * as c from './constants';
+import * as C from './constants';
 
 const actions = createActions(
   {
-    [c.RECEIVE_POSTS]: subreddit => ({
+    [C.RECEIVE_POSTS]: subreddit => ({
       subreddit,
       posts: json.data.children.map(child => child.data),
-      recerivedAt: Date.now()
-    })
+      receivedAt: Date.now()
+    }),
+    [C.INVALIDATE_SUBREDDIT]: subreddit => ({ subreddit }),
+    [C.REQUEST_POST]: subreddit => ({ subreddit })
   },
-  c.SELECT_SUBREDDIT,
-  c.INVALIDATE_SUBREDDIT,
-  c.REQUEST_POST
+  C.SELECT_SUBREDDIT
 );
 
 export default actions;

+ 48 - 1
src/reducers/index.js

@@ -1,2 +1,49 @@
-import * as c from '../actions/constants';
+import { handleAction, handleActions, combineActions } from 'redux-actions';
+import { combineReducers } from 'redux';
+import * as C from '../actions/constants';
 import actions from '../actions/';
+
+const selectedSubreddit = handleAction(
+  C.SELECT_SUBREDDIT,
+  (state, { payload }) => payload,
+  'reactjs'
+);
+
+const posts = handleActions(
+  {
+    [C.INVALIDATE_SUBREDDIT]: (state, { payload }) => ({
+      ...state,
+      didInvalidate: true
+    }),
+    [C.REQUEST_POST]: (state, { payload }) => ({
+      ...state,
+      isFetching: true,
+      didInvalidate: false
+    }),
+    [C.RECEIVE_POSTS]: (state, { payload }) => ({
+      ...state,
+      isFetching: false,
+      didInvalidate: false,
+      items: payload.posts,
+      lastUpdate: payload.receivedAt
+    })
+  },
+  {
+    isFetching: false,
+    didInvalidate: false,
+    items: []
+  }
+);
+
+const postsBySubreddit = handleAction(
+  combineActions(C.INVALIDATE_SUBREDDIT, C.REQUEST_POST, C.RECEIVE_POSTS),
+  (state, action) => {
+    const subreddit = action.payload.subreddit;
+    return {
+      [subreddit]: posts(state[subreddit], action)
+    };
+  },
+  {}
+);
+const reducer = combineReducers({ selectedSubreddit, postsBySubreddit });
+export default reducer;