Repository: ctrlplusb/easy-peasy
Pull request #127 (2019-03-21 05:50:59)

Attach mockActions middleware as the last one.
When custom middleware fires actions, mockActions middleware is able to intercept these as well.
Provide a test case.

ivosh: #127 
ivosh: Referenced issue: #125 
codecov[bot]: # [Codecov](https://codecov.io/gh/ctrlplusb/easy-peasy/pull/127?src=pr&el=h1) Report
> Merging [#127](https://codecov.io/gh/ctrlplusb/easy-peasy/pull/127?src=pr&el=desc) into [master](https://codecov.io/gh/ctrlplusb/easy-peasy/commit/4795277820149da0f08894b60b90af0a2005c29f?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/ctrlplusb/easy-peasy/pull/127/graphs/tree.svg?width=650&token=8XR3ly4qMt&height=150&src=pr)](https://codecov.io/gh/ctrlplusb/easy-peasy/pull/127?src=pr&el=tree)

```diff
@@          Coverage Diff          @@
##           master   #127   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files           9      9           
  Lines         295    295           
  Branches       46     46           
=====================================
  Hits          295    295
```


| [Impacted Files](https://codecov.io/gh/ctrlplusb/easy-peasy/pull/127?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/create-store.js](https://codecov.io/gh/ctrlplusb/easy-peasy/pull/127/diff?src=pr&el=tree#diff-c3JjL2NyZWF0ZS1zdG9yZS5qcw==) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/ctrlplusb/easy-peasy/pull/127?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/ctrlplusb/easy-peasy/pull/127?src=pr&el=footer). Last update [4795277...9742055](https://codecov.io/gh/ctrlplusb/easy-peasy/pull/127?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/README.md b/README.md
index cc163f8..a6414ac 100644
--- a/README.md
+++ b/README.md
@@ -1513,7 +1513,7 @@ const notificationModel = {
     on(userModel.loggedIn, thunk(async (actions, payload, helpers) => {
       const msg = `${payload.username} logged in`
       await auditService.log(msg)
-    }))
+    }));
 
     // Action handler
     on(userModel.logOut, action((state) => {
@@ -1544,13 +1544,13 @@ const model = {
 
   listeners: listen((on) => {
     //      👇 passing in action name
-    on('ROUTE_CHANGED', (actions, payload) => {
+    on('ROUTE_CHANGED', action(actions, payload) => {
       //                            👆
       // We won't know the type of payload, so it will be "any".
       // You will have to annotate it manually if you are using
       // Typescript and care about the payload type.
       actions.set(`Route was changed`);
-    });
+    }));
   })
 };
 ```
diff --git a/src/create-store.js b/src/create-store.js
index d529d4c..e259568 100644
--- a/src/create-store.js
+++ b/src/create-store.js
@@ -35,7 +35,7 @@ export default function createStore(model, options = {}) {
 
   let mockedActions = [];
 
-  const mockActionsMiddlware = () => next => action => {
+  const mockActionsMiddleware = () => next => action => {
     if (mockActions) {
       mockedActions.push(action);
       return undefined;
@@ -106,8 +106,8 @@ export default function createStore(model, options = {}) {
       applyMiddleware(
         reduxThunk,
         dispatchActionStringListeners,
-        mockActionsMiddlware,
         ...middleware,
+        mockActionsMiddleware,
       ),
       ...enhancers,
     ),


Test patch:
diff --git a/src/__tests__/easy-peasy.test.js b/src/__tests__/easy-peasy.test.js
index 28c9b59..bfb8bfe 100644
--- a/src/__tests__/easy-peasy.test.js
+++ b/src/__tests__/easy-peasy.test.js
@@ -502,6 +502,52 @@ describe('store', () => {
     store.dispatch.logFullState();
   });
 
+  test('allows custom middleware with mockActions=true', () => {
+    // arrange
+    const customMiddleware = store => next => _action => {
+      if (_action.customMiddleware) {
+        // Unfortunately 'store' is plain Redux store, not easy-peasy's one.
+        // So we have to use string named action listeners.
+        next(store.dispatch({ type: 'API_REQUEST' }));
+        // here is API interaction etc.
+        next(
+          store.dispatch({ type: 'API_RESPONSE', payload: { success: true } }),
+        );
+      }
+      next(_action);
+    };
+    const store = createStore(
+      {
+        error: false,
+        saved: action((state, { success }) => {
+          state.error = !success;
+        }),
+        listeners: listen(on => {
+          on(
+            'API_RESPONSE',
+            thunk(async (actions, payload) => {
+              await actions.saved(payload);
+            }),
+          );
+        }),
+      },
+      { middleware: [customMiddleware], mockActions: true },
+    );
+
+    // act
+    store.dispatch({ customMiddleware: 'operateOnAPI' });
+
+    // assert
+    expect(store.getMockedActions()).toEqual([
+      { type: 'API_REQUEST' },
+      undefined,
+      { type: '@action.saved', payload: { success: true } },
+      { type: 'API_RESPONSE', payload: { success: true } },
+      undefined,
+      { customMiddleware: 'operateOnAPI' },
+    ]);
+  });
+
   test('allows custom enhancers', () => {
     // arrange
     const defaultState = { foo: 'bar' };