{"id":28545120,"url":"https://github.com/moxystudio/redux-await-actions","last_synced_at":"2026-05-09T19:34:51.538Z","repository":{"id":42669288,"uuid":"236089850","full_name":"moxystudio/redux-await-actions","owner":"moxystudio","description":"Waits for specific actions to be dispatched or a timeout expires.","archived":false,"fork":false,"pushed_at":"2023-01-07T23:05:30.000Z","size":2059,"stargazers_count":1,"open_issues_count":15,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-18T06:50:44.922Z","etag":null,"topics":["action","async","redux","test","timeout","wait"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/moxystudio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2020-01-24T21:53:22.000Z","updated_at":"2021-02-16T20:14:12.000Z","dependencies_parsed_at":"2023-02-08T03:15:27.985Z","dependency_job_id":null,"html_url":"https://github.com/moxystudio/redux-await-actions","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/moxystudio/redux-await-actions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fredux-await-actions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fredux-await-actions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fredux-await-actions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fredux-await-actions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moxystudio","download_url":"https://codeload.github.com/moxystudio/redux-await-actions/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fredux-await-actions/sbom","scorecard":{"id":661854,"data":{"date":"2025-08-11","repo":{"name":"github.com/moxystudio/redux-await-actions","commit":"2d21a37fa3673fab899b3dad83b8e70252f59631"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/7 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/node-ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":4,"reason":"dependency not pinned by hash detected -- score normalized to 4","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node-ci.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/moxystudio/redux-await-actions/node-ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node-ci.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/moxystudio/redux-await-actions/node-ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node-ci.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/moxystudio/redux-await-actions/node-ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/node-ci.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/moxystudio/redux-await-actions/node-ci.yml/master?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   1 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 1 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"37 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-44c6-4v22-4mhx","Warn: Project is vulnerable to: GHSA-4x5v-gmq8-25ch","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v","Warn: Project is vulnerable to: GHSA-38fc-wpqx-33j7","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T16:26:42.743Z","repository_id":42669288,"created_at":"2025-08-21T16:26:42.743Z","updated_at":"2025-08-21T16:26:42.743Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32833202,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["action","async","redux","test","timeout","wait"],"created_at":"2025-06-09T23:06:38.200Z","updated_at":"2026-05-09T19:34:51.530Z","avatar_url":"https://github.com/moxystudio.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# redux-await-actions\n\n[![npm version][npm-image]][npm-url] [![ci][github-ci-image]][github-ci-url] [![codecov][codecov-image]][codecov-url]\n\n[npm-url]:https://www.npmjs.com/package/@moxy/redux-await-actions\n[npm-image]:https://img.shields.io/npm/v/@moxy/redux-await-actions.svg\n[github-ci-url]:https://github.com/moxystudio/redux-await-actions/actions\n[github-ci-image]:https://github.com/moxystudio/redux-await-actions/workflows/Node%20CI/badge.svg\n[codecov-url]:https://codecov.io/gh/moxystudio/redux-await-actions?branch=master\n[codecov-image]:https://codecov.io/gh/moxystudio/redux-await-actions/badge.svg?branch=master\n\n\u003e Waits for specific actions to be dispatched or a timeout expires.\n\n## Installation\n\n`$ npm install @moxy/redux-await-actions --save-dev`\n\n## Motivation\n\nConsider the following example:\n\n```js\nimport thunkMiddleware from 'redux-thunk';\nimport { createStore, applyMiddleware, compose } from 'redux';\n\nfunction login(username, password) {\n    return async (dispatch) =\u003e {\n        dispatch({ type: 'LOGIN_START', payload: { username, password } });\n\n        try {\n            const user = await fetch('/login', {\n                headers: { 'Content-Type': 'application/json' },\n                method: 'POST',\n                body: JSON.stringify({ username, password })\n            });\n\n            dispatch({ type: 'LOGIN_SUCCESS', payload: user });\n        } catch (err) {\n            dispatch({ type: 'LOGIN_FAIL', payload: err });\n\n            throw err;\n        }\n\n        // Side-effect: fetch orders asynchronously\n        // This action could be dispatched from a middleware as well instead. See below.\n        dispatch(fetchOrders());\n    }\n}\n\nconst middlewares = [\n    thunkMiddleware,\n    ({ dispatch, getState }) =\u003e (next) =\u003e (action) =\u003e {\n        const result = next(action);\n\n        if (action.type === 'LOGIN_SUCCESS') {\n            // Side-effect: fetch orders asynchronously\n            dispatch(fetchOrders());\n        }\n\n        return result;\n    }\n];\nconst enhancer = compose(applyMiddleware(...middlewares));\nconst store = createStore(/* reducer */, /* initial state */, enhancer);\n\nstore.dispatch(login('username', 'password')).then(() =\u003e {\n    // For the sake of this example, assume Redux provides a getActions method\n    expect(store.getActions()).toContain([\n        'LOGIN_START',\n        'LOGIN_SUCCESS',\n        'FETCH_ORDERS_SUCCESS'\n    ]);\n});\n```\n\nThe assertion above will fail because `FETCH_ORDERS_SUCCESS` will not yet exist in the stack of actions. To solve this, one can use `setTimeout` explicitly in each test:\n\n```js\nstore.dispatch(login('username', 'password'));\n\nsetTimeout(() =\u003e expect(store.getActions()).toContain([\n    'LOGIN_START',\n    'FETCH_ORDERS_SUCCESS'\n]), 50);\n```\n\nHowever, this is not pretty and is error-prone. This library makes this easier for you. It works with both [redux-mock-store](https://github.com/arnaudbenard/redux-mock-store) and real redux store. It allows you to wait out for an arbitrary number of actions dispatched asynchronously as a result a side-effect by matching the actual contents of each dispatched action with the expected contents.\n\n## Usage\n\nIn order to ensure the `store` passed to `redux-await-actions` has a consistent interface when using either store (real and mock), a store enhancer is provided as an adapter to implement `getActions` and `clearActions` for the real store. The enhancer is exported as `mockStoreAdapter` Check the examples below.\n\n### Example #1: action types\n\nSupply the action types to wait for.\n\n#### Real store\n\n```js\nimport awaitActions from '@moxy/redux-await-actions';\nimport configureStore from 'redux';\nimport thunkMiddleware from 'redux-thunk';\n\nconst middlewareEnhancer = compose(applyMiddleware(thunkMiddleware));\nconst composedEnhancers = compose(middlewareEnhancer, awaitActions.mockStoreAdapter);\nconst store = createStore(/* reducer */, /* initial state */, composedEnhancers);\n\nstore.dispatch(login('username', 'password'));\n\nawait waitForActions(store, ['LOGIN_START', 'FETCH_ORDERS_SUCCESS']);\n```\n\n#### Mock store\n\n```js\nimport awaitActions from '@moxy/redux-await-actions';\nimport configureStore from 'redux-mock-store';\nimport thunkMiddleware from 'redux-thunk';\n\nconst store = configureStore([thunkMiddleware])();\n\nstore.dispatch(login('username', 'password'));\n\nawait waitForActions(store, ['LOGIN_START', 'FETCH_ORDERS_SUCCESS']);\n```\n\n### Example #2: action objects\n\nSupply the action objects to wait for, matching a subset of the properties of the dispatched actions. It performs a deep comparison between property values of dispatched and expected actions to determine whether the expected actions are partially contained in the stack of dispatched actions.\n\n#### Mock store\n\n```js\nimport awaitActions from '@moxy/redux-await-actions';\nimport configureStore from 'redux-mock-store';\nimport thunkMiddleware from 'redux-thunk';\n\nconst store = configureStore([thunkMiddleware])();\n\nstore.dispatch(login('username', 'password'));\n// { type: 'LOGIN_START', payload: { username: 'username' } }\n// matches\n// { type: 'LOGIN_START', payload: { username: 'username', password } }\n//\n// { type: 'FETCH_ORDERS_SUCCESS' }\n// matches\n// { type: 'FETCH_ORDERS_SUCCESS', payload: orders }\n\nawait waitForActions(store, [\n    {\n        type: 'LOGIN_START',\n        payload: { username: 'username' },\n    },\n    {\n        type: 'FETCH_ORDERS_SUCCESS',\n    },\n\n]);\n```\n\n#### Real store\n\n```js\nimport configureStore from 'redux';\nimport thunkMiddleware from 'redux-thunk';\n\nconst middlewareEnhancer = compose(applyMiddleware(thunkMiddleware));\nconst composedEnhancers = compose(middlewareEnhancer, awaitActions.mockStoreAdapter);\nconst store = createStore(/* reducer */, /* initial state */, composedEnhancers);\n\nstore.dispatch(login('username', 'password'));\n// { type: 'LOGIN_START', payload: { username: 'username' } }\n// matches\n// { type: 'LOGIN_START', payload: { username: 'username', password } }\n//\n// { type: 'FETCH_ORDERS_SUCCESS' }\n// matches\n// { type: 'FETCH_ORDERS_SUCCESS', payload: orders }\n\nawait waitForActions(store, [\n    {\n        type: 'LOGIN_START',\n        payload: { username: 'username' },\n    },\n    {\n        type: 'FETCH_ORDERS_SUCCESS',\n    },\n\n]);\n```\n\n## API\n\n### awaitActions(store, actions, [options])\n\nReturns a `Promise` which fulfills if all `actions` are dispatched before the timeout expires. The `Promise` has a `.cancel()` function which, if called, will reject the `Promise`.\n\nThe `Promise` might be rejected:\n\n* as a result of timeout expiration, throwing `TimeoutError`\n* as a result of `.cancel()` invocation, throwing `CancelledError`\n* when the action's matcher throws `MismatchError`\n\n**NOTE:** Subsequent calls to `awaitActions` with the same actions should be preceded by a call to `store.clearActions()`, otherwise the returned `Promise` will resolve immediately.\n\n#### store\n\nType: `Object`\n\nThe `redux-mock-store` or `redux` store enhanced with `awaitActions.mockStoreAdapter`.\n\n#### actions\n\nType: `Object | String | Array | Function`\n\nThe actions to wait for. It can be either:\n\n* `String`: an action type string.\n* `Object`: an action object.\n* `Array` of either\n    * action objects;\n    * action type strings;\n    * action objects mixed with action type strings.\n\n#### options\n\n##### timeout\n\nType: `Number`   \nDefault: 2000\n\nThe timeout given in milliseconds.\n\n##### throttleWait\n\nType: `Number`   \nDefault: 0\n\nSpecifies the time in milliseconds that every invocation to the action's matcher take place at since the last invocation. When set to zero, throttling is disabled.\n\nWhen throttling is enabled, the `matcher` will be called at most once per `throttleWait` milliseconds receiving the array of actions dispatched until that time. If the `matcher` does not resolve the `Promise` until `timeout` milliseconds have elapsed, the `Promise` is rejected throwing `TimeoutError`.\nThis feature is useful when one needs to wait for several actions or a burst of actions to be dispatched, effectively skip invocations to the action's matcher until the Redux store \"settles\" to avoid running complex action comparison logic in the meantime and improve performance.\n\n##### matcher\n\nType: `Function`   \nDefault: `awaitActions.dispatchOrderMatcher`\n\nSupplies custom behavior to specify how expected and dispatched actions should be compared. The function accepts two arguments: the array of expected actions and dispatched actions.\n\nThe matcher must either:\n\n* return `true` to indicate a match has occurred and fulfill the `Promise`.\n* return `false` to indicate a match is yet to occur and the `Promise` remains in pending state.\n* throw `MismatchError` to indicate a match will not occur anymore and reject the `Promise`.\n\nTwo built-in matchers are already shipped:\n\n* `dispatchOrderMatcher` performs a comparison between the specified order of expected actions against the order of arrival of dispatched actions. On the first mismatch detected, `MismatchError` is thrown for early rejection.\n* `wasDispatchedMatcher` matcher is a less strict matcher which checks whether expected actions are contained within dispatched actions.\n\nBoth matchers perform a *partial deep comparison* between dispatched and expected actions, as per [Lodash's isMatch()](https://lodash.com/docs/4.17.4#isMatch).\n\nExample of a custom matcher implementation:\n\n```js\nimport awaitActions from '@moxy/redux-await-actions';\nimport configureStore from 'redux-mock-store';\nimport thunkMiddleware from 'redux-thunk';\n\nconst store = configureStore([thunkMiddleware])();\nconst expectedActions = [\n    { type: 'LOGIN_START', payload: { username: 'username' } },\n    { type: 'FETCH_ORDERS_SUCCESS' }\n];\n\nstore.dispatch(login('username', 'password'));\n\n// Throws if LOGIN_FAIL is dispatched or\n// Matches when LOGIN_START and FETCH_ORDERS_SUCCESS are dispatched\nawaitActions(store, expectedActions, { matcher: (expectedActions, storeActions) =\u003e {\n    const hasLoginFail = storeActions.some((action) =\u003e action.type === 'LOGIN_FAIL');\n\n    if (hasLoginFail) {\n        throw new waitForActions.MismatchError();\n    }\n\n    const hasLoginStart = storeActions.some((action) =\u003e action.type === 'LOGIN_START' \u0026\u0026 action.payload.username === 'username');\n    const hasFetchOrdersSuccess = storeActions.some((action) =\u003e action.type === 'FETCH_ORDERS_SUCCESS');\n\n    return hasLoginStart \u0026\u0026 hasFetchOrdersSuccess;\n}})\n.then(() =\u003e {\n    // Expected actions were dispatched\n})\n.catch((err) =\u003e {\n    // MismatchError\n});\n```\n\n## Tests\n\n`$ npm test`   \n`$ npm test -- --watch` during development\n\n\n## License\n\n[MIT License](http://opensource.org/licenses/MIT)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoxystudio%2Fredux-await-actions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoxystudio%2Fredux-await-actions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoxystudio%2Fredux-await-actions/lists"}