From b9912dd776e9fda532228f3fa99f3c8fe277c19e Mon Sep 17 00:00:00 2001 From: Jeff Tribble Date: Mon, 15 Feb 2016 09:46:36 -0700 Subject: [PATCH 1/6] Use local installation of eslint for linting --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8a6fd6b..1dd4ac5 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "build": "babel src --out-dir lib", "clean": "rimraf lib coverage", "cover": "babel-node ./node_modules/.bin/babel-istanbul cover test/index.js | tap-spec", - "lint": "eslint src test", + "lint": "./node_modules/eslint/bin/eslint.js src test", "prepublish": "npm run lint && npm test && npm run clean && npm run build", "test": "babel-node test/index.js | tap-spec" }, From eb7d6b167ba8c895879d473da7ec9164b45e9ceb Mon Sep 17 00:00:00 2001 From: Jeff Tribble Date: Mon, 15 Feb 2016 09:50:02 -0700 Subject: [PATCH 2/6] Add root:true option to eslint config so that we don't inherit rules from parent configs --- .eslintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc b/.eslintrc index 31496e1..1b8173a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -9,6 +9,7 @@ "experimentalObjectRestSpread": true, "modules": true }, + "root": true, "rules": { "babel/arrow-parens": [2, "always"], "no-underscore-dangle": 0, From 7dc2a28a68aef101f95a606f9c48285507e5f59b Mon Sep 17 00:00:00 2001 From: Jeff Tribble Date: Mon, 15 Feb 2016 10:35:26 -0700 Subject: [PATCH 3/6] Update to latest babel and eslint (tests failed on install, updating to latest resolved the issue) --- .babelrc | 6 +----- package.json | 16 +++++++++------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.babelrc b/.babelrc index 8c12912..eaf3238 100644 --- a/.babelrc +++ b/.babelrc @@ -1,7 +1,3 @@ { - "stage": 0, - "loose": "all", - "optional": [ - "runtime" - ] + "presets": ["es2015", "stage-0"] } diff --git a/package.json b/package.json index 1dd4ac5..5cdafed 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "build": "babel src --out-dir lib", "clean": "rimraf lib coverage", "cover": "babel-node ./node_modules/.bin/babel-istanbul cover test/index.js | tap-spec", - "lint": "./node_modules/eslint/bin/eslint.js src test", + "lint": "eslint src test", "prepublish": "npm run lint && npm test && npm run clean && npm run build", "test": "babel-node test/index.js | tap-spec" }, @@ -26,17 +26,19 @@ }, "license": "MIT", "dependencies": { - "babel-runtime": "^5.8.25", + "babel-runtime": "^6.5.0", "isomorphic-fetch": "^2.1.1", "lodash.isplainobject": "^3.2.0" }, "devDependencies": { - "babel": "^5.8.23", - "babel-eslint": "^4.1.3", - "babel-istanbul": "^0.3.20", + "babel-cli": "^6.5.1", + "babel-eslint": "^4.1.8", + "babel-istanbul": "^0.6.0", + "babel-preset-es2015": "^6.5.0", + "babel-preset-stage-0": "^6.5.0", "coveralls": "^2.11.4", - "eslint": "^1.6.0", - "eslint-plugin-babel": "^2.1.1", + "eslint": "^2.0.0", + "eslint-plugin-babel": "^3.1.0", "nock": "^2.15.0", "normalizr": "^1.1.0", "rimraf": "^2.4.3", From a1078fd2bbec8efdd550063e6f7a663525299d0c Mon Sep 17 00:00:00 2001 From: Jeff Tribble Date: Mon, 15 Feb 2016 11:32:13 -0700 Subject: [PATCH 4/6] Use RSAA string instead of CALL_API symbol; update all source code & tests; modify babel runtime config (add transform plugin) --- .babelrc | 1 + README.md | 104 ++++++++++----------- package.json | 1 + src/CALL_API.js | 10 -- src/RSAA.js | 10 ++ src/index.js | 6 +- src/middleware.js | 18 ++-- src/util.js | 2 +- src/validation.js | 38 ++++---- test/index.js | 234 +++++++++++++++++++++++----------------------- 10 files changed, 213 insertions(+), 211 deletions(-) delete mode 100644 src/CALL_API.js create mode 100644 src/RSAA.js diff --git a/.babelrc b/.babelrc index eaf3238..c71d366 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,4 @@ { + "plugins": ["transform-runtime"], "presets": ["es2015", "stage-0"] } diff --git a/README.md b/README.md index ad48529..b9af9ee 100644 --- a/README.md +++ b/README.md @@ -28,17 +28,17 @@ redux-api-middleware This middleware receives [*Redux Standard API-calling Actions*](#redux-standard-api-calling-actions) (RSAAs) and dispatches [*Flux Standard Actions*](#flux-standard-actions) (FSAs) to the next middleware. -RSAAs are identified by the presence of a `[CALL_API]` property, where [`CALL_API`](#call_api) is a `Symbol` defined in, and exported by `redux-api-middleware`. They contain information describing an API call and three different types of FSAs, known as the *request*, *success* and *failure* FSAs. +RSAAs are identified by the presence of an `[RSAA]` property, where [`RSAA`](#rsaa) is a `String` constant defined in, and exported by `redux-api-middleware`. They contain information describing an API call and three different types of FSAs, known as the *request*, *success* and *failure* FSAs. ### A simple example The following is a minimal RSAA action: ```js -import { CALL_API } from `redux-api-middleware`; +import { RSAA } from `redux-api-middleware`; // RSAA = '@@redux-api-middleware/RSAA' { - [CALL_API]: { + [RSAA]: { endpoint: 'http://www.example.com/api/users', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'] @@ -119,27 +119,27 @@ const store = configureStore(initialState); ### Defining the API call -The parameters of the API call are specified by root properties of the `[CALL_API]` property of an RSAA. +The parameters of the API call are specified by root properties of the `[RSAA]` property of an RSAA. -#### `[CALL_API].endpoint` +#### `[RSAA].endpoint` The URL endpoint for the API call. It is usually a string, be it a plain old one or an ES2015 template string. It may also be a function taking the state of your Redux store as its argument, and returning such a string. -#### `[CALL_API].method` +#### `[RSAA].method` The HTTP method for the API call. It must be one of the strings `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE` or `OPTIONS`, in any mixture of lowercase and uppercase letters. -#### `[CALL_API].body` +#### `[RSAA].body` The body of the API call. -`redux-api-middleware` uses [`isomorphic-fetch`](https://github.com/matthew-andrews/isomorphic-fetch) to make the API call. `[CALL_API].body` should hence be a valid body according to the the [fetch specification](https://fetch.spec.whatwg.org). In most cases, this will be a JSON-encoded string or a [`FormData`](https://developer.mozilla.org/en/docs/Web/API/FormData) object. +`redux-api-middleware` uses [`isomorphic-fetch`](https://github.com/matthew-andrews/isomorphic-fetch) to make the API call. `[RSAA].body` should hence be a valid body according to the the [fetch specification](https://fetch.spec.whatwg.org). In most cases, this will be a JSON-encoded string or a [`FormData`](https://developer.mozilla.org/en/docs/Web/API/FormData) object. -#### `[CALL_API].headers` +#### `[RSAA].headers` The HTTP headers for the API call. @@ -147,7 +147,7 @@ It is usually an object, with the keys specifying the header names and the value ```js { - [CALL_API]: { + [RSAA]: { ... headers: { 'Content-Type': 'application/json' } ... @@ -157,7 +157,7 @@ It is usually an object, with the keys specifying the header names and the value It may also be a function taking the state of your Redux store as its argument, and returning an object of headers as above. -#### `[CALL_API].credentials` +#### `[RSAA].credentials` Whether or not to send cookies with the API call. @@ -171,48 +171,48 @@ It must be one of the following strings: In some cases, the data you would like to fetch from the server may already be cached in you Redux store. Or you may decide that the current user does not have the necessary permissions to make some request. -You can tell `redux-api-middleware` to not make the API call through `[CALL_API].bailout`. If the value is `true`, the RSAA will die here, and no FSA will be passed on to the next middleware. +You can tell `redux-api-middleware` to not make the API call through `[RSAA].bailout`. If the value is `true`, the RSAA will die here, and no FSA will be passed on to the next middleware. -A more useful possibility is to give `[CALL_API].bailout` a function. At runtime, it will be passed the state of your Redux store as its only argument, if the return value of the function is `true`, the API call will not be made. +A more useful possibility is to give `[RSAA].bailout` a function. At runtime, it will be passed the state of your Redux store as its only argument, if the return value of the function is `true`, the API call will not be made. ### Lifecycle -The `[CALL_API].types` property controls the output of `redux-api-middleware`. The simplest form it can take is an array of length 3 consisting of string constants (or symbols), as in our [example](#a-simple-example) above. This results in the default behavior we now describe. +The `[RSAA].types` property controls the output of `redux-api-middleware`. The simplest form it can take is an array of length 3 consisting of string constants (or symbols), as in our [example](#a-simple-example) above. This results in the default behavior we now describe. -1. When `redux-api-middleware` receives an action, it first checks whether it has a `[CALL_API]` property. If it does not, it was clearly not intended for processing with `redux-api-middleware`, and so it is unceremoniously passed on to the next middleware. +1. When `redux-api-middleware` receives an action, it first checks whether it has an `[RSAA]` property. If it does not, it was clearly not intended for processing with `redux-api-middleware`, and so it is unceremoniously passed on to the next middleware. 2. It is now time to validate the action against the [RSAA definition](#redux-standard-api-calling-actions). If there are any validation errors, a *request* FSA will be dispatched (if at all possible) with the following properties: - - `type`: the string constant in the first position of the `[CALL_API].types` array; + - `type`: the string constant in the first position of the `[RSAA].types` array; - `payload`: an [`InvalidRSAA`](#invalidrsaa) object containing a list of said validation errors; - `error: true`. `redux-api-middleware` will perform no further operations. In particular, no API call will be made, and the incoming RSAA will die here. 3. Now that `redux-api-middleware` is sure it has received a valid RSAA, it will try making the API call. If everything is alright, a *request* FSA will be dispatched with the following property: - - `type`: the string constant in the first position of the `[CALL_API].types` array. + - `type`: the string constant in the first position of the `[RSAA].types` array. But errors may pop up at this stage, for several reasons: - - `redux-api-middleware` has to call those of `[CALL_API].bailout`, `[CALL_API].endpoint` and `[CALL_API].headers` that happen to be a function, which may throw an error; - - `isomorphic-fetch` may throw an error: the RSAA definition is not strong enough to preclude that from happening (you may, for example, send in a `[CALL_API].body` that is not valid according to the fetch specification — mind the SHOULDs in the [RSAA definition](#redux-standard-api-calling-actions)); + - `redux-api-middleware` has to call those of `[RSAA].bailout`, `[RSAA].endpoint` and `[RSAA].headers` that happen to be a function, which may throw an error; + - `isomorphic-fetch` may throw an error: the RSAA definition is not strong enough to preclude that from happening (you may, for example, send in a `[RSAA].body` that is not valid according to the fetch specification — mind the SHOULDs in the [RSAA definition](#redux-standard-api-calling-actions)); - a network failure occurs (the network is unreachable, the server responds with an error,...). If such an error occurs, a different *request* FSA will be dispatched (*instead* of the one described above). It will contain the following properties: - - `type`: the string constant in the first position of the `[CALL_API].types` array; + - `type`: the string constant in the first position of the `[RSAA].types` array; - `payload`: a [`RequestError`](#requesterror) object containing an error message; - `error: true`. 4. If `redux-api-middleware` receives a response from the server with a status code in the 200 range, a *success* FSA will be dispatched with the following properties: - - `type`: the string constant in the second position of the `[CALL_API].types` array; + - `type`: the string constant in the second position of the `[RSAA].types` array; - `payload`: if the `Content-Type` header of the response is set to something JSONy (see [*Success* type descriptors](#success-type-descriptors) below), the parsed JSON response of the server, or undefined otherwise. If the status code of the response falls outside that 200 range, a *failure* FSA will dispatched instead, with the following properties: - - `type`: the string constant in the third position of the `[CALL_API].types` array; + - `type`: the string constant in the third position of the `[RSAA].types` array; - `payload`: an [`ApiError`](#apierror) object containing the message `` `${status} - ${statusText}` ``; - `error: true`. ### Customizing the dispatched FSAs -It is possible to customize the output of `redux-api-middleware` by replacing one or more of the string constants (or symbols) in `[CALL_API].types` by a type descriptor. +It is possible to customize the output of `redux-api-middleware` by replacing one or more of the string constants (or symbols) in `[RSAA].types` by a type descriptor. A *type descriptor* is a plain JavaScript object that will be used as a blueprint for the dispatched FSAs. As such, type descriptors must have a `type` property, intended to house the string constant or symbol specifying the `type` of the resulting FSAs. @@ -231,7 +231,7 @@ For example, if you want your *request* FSA to have the URL endpoint of the API ```js // Input RSAA { - [CALL_API]: { + [RSAA]: { endpoint: 'http://www.example.com/api/users', method: 'GET', types: [ @@ -257,7 +257,7 @@ If you do not need access to the action itself or the state of your Redux store, ```js // Input RSAA { - [CALL_API]: { + [RSAA]: { endpoint: 'http://www.example.com/api/users', method: 'GET', types: [ @@ -296,7 +296,7 @@ const userSchema = new Schema('users'); // Input RSAA { - [CALL_API]: { + [RSAA]: { endpoint: 'http://www.example.com/api/users', method: 'GET', types: [ @@ -357,7 +357,7 @@ For example, if you want the status code and status message of a unsuccessful AP ```js { - [CALL_API]: { + [RSAA]: { endpoint: 'http://www.example.com/api/users/1', method: 'GET', types: [ @@ -396,9 +396,9 @@ By default, *failure* FSAs will not contain a `meta` property, while their `payl The following objects are exported by `redux-api-middleware`. -#### `CALL_API` +#### `RSAA` -A JavaScript `Symbol` whose presence as a key in an action signals that `redux-api-middleware` should process said action. +A JavaScript `String` whose presence as a key in an action signals that `redux-api-middleware` should process said action. #### `apiMiddleware` @@ -406,7 +406,7 @@ The Redux middleware itself. #### `isRSAA(action)` -A function that returns `true` if `action` has a `[CALL_API]` property, and `false` otherwise. +A function that returns `true` if `action` has an `[RSAA]` property, and `false` otherwise. #### `validateRSAA(action)` @@ -508,65 +508,65 @@ The optional `meta` property MAY be any type of value. It is intended for any ex ### Redux Standard API-calling Actions The definition of a *Redux Standard API-calling Action* below is the one used to validate RSAA actions. As explained in [Lifecycle](#lifecycle), - - actions without a `[CALL_API]` will be passed to the next middleware without any modifications; - - actions with a `[CALL_API]` property that fail validation will result in an error *request* FSA. + - actions without an `[RSAA]` property will be passed to the next middleware without any modifications; + - actions with an `[RSAA]` property that fail validation will result in an error *request* FSA. A *Redux Standard API-calling Action* MUST - be a plain JavaScript object, -- have a `[CALL_API]` property. +- have an `[RSAA]` property. A *Redux Standard API-calling Action* MUST NOT -- include properties other than `[CALL_API]`. +- include properties other than `[RSAA]`. -#### `[CALL_API]` +#### `[RSAA]` -The `[CALL_API]` property MUST +The `[RSAA]` property MUST - be a plain JavaScript Object, - have an `endpoint` property, - have a `method` property, - have a `types` property. -The `[CALL_API]` property MAY +The `[RSAA]` property MAY - have a `body` property, - have a `headers` property, - have a `credentials` property, - have a `bailout` property. -The `[CALL_API]` property MUST NOT +The `[RSAA]` property MUST NOT - include properties other than `endpoint`, `method`, `types`, `body`, `headers`, `credentials`, and `bailout`. -#### `[CALL_API].endpoint` +#### `[RSAA].endpoint` -The `[CALL_API].endpoint` property MUST be a string or a function. In the second case, the function SHOULD return a string. +The `[RSAA].endpoint` property MUST be a string or a function. In the second case, the function SHOULD return a string. -#### `[CALL_API].method` +#### `[RSAA].method` -The `[CALL_API].method` property MUST be one of the strings `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE` or `OPTIONS`, in any mixture of lowercase and uppercase letters. +The `[RSAA].method` property MUST be one of the strings `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE` or `OPTIONS`, in any mixture of lowercase and uppercase letters. -#### `[CALL_API].body` +#### `[RSAA].body` -The optional `[CALL_API].body` property SHOULD be a valid body according to the the [fetch specification](https://fetch.spec.whatwg.org). +The optional `[RSAA].body` property SHOULD be a valid body according to the the [fetch specification](https://fetch.spec.whatwg.org). -#### `[CALL_API].headers` +#### `[RSAA].headers` -The optional `[CALL_API].headers` property MUST be a plain JavaScript object or a function. In the second case, the function SHOULD return a plain JavaScript object. +The optional `[RSAA].headers` property MUST be a plain JavaScript object or a function. In the second case, the function SHOULD return a plain JavaScript object. -#### `[CALL_API].credentials` +#### `[RSAA].credentials` -The optional `[CALL_API].credentials` property MUST be one of the strings `omit`, `same-origin` or `include`. +The optional `[RSAA].credentials` property MUST be one of the strings `omit`, `same-origin` or `include`. -#### `[CALL_API].bailout` +#### `[RSAA].bailout` -The optional `[CALL_API].bailout` property MUST be a boolean or a function. +The optional `[RSAA].bailout` property MUST be a boolean or a function. -#### `[CALL_API].types` +#### `[RSAA].types` -The `[CALL_API].types` property MUST be an array of length 3. Each element of the array MUST be a string, a `Symbol`, or a type descriptor. +The `[RSAA].types` property MUST be an array of length 3. Each element of the array MUST be a string, a `Symbol`, or a type descriptor. #### Type descriptors diff --git a/package.json b/package.json index 5cdafed..ec67e2f 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ }, "license": "MIT", "dependencies": { + "babel-plugin-transform-runtime": "^6.5.2", "babel-runtime": "^6.5.0", "isomorphic-fetch": "^2.1.1", "lodash.isplainobject": "^3.2.0" diff --git a/src/CALL_API.js b/src/CALL_API.js deleted file mode 100644 index d1821d4..0000000 --- a/src/CALL_API.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Symbol key that carries API call info interpreted by this Redux middleware. - * - * @constant {symbol} - * @access public - * @default - */ -const CALL_API = Symbol('Call API'); - -export default CALL_API; diff --git a/src/RSAA.js b/src/RSAA.js new file mode 100644 index 0000000..0b926a9 --- /dev/null +++ b/src/RSAA.js @@ -0,0 +1,10 @@ +/** + * String key that carries API call info interpreted by this Redux middleware. + * + * @constant {string} + * @access public + * @default + */ +const RSAA = '@@redux-api-middleware/RSAA'; + +export default RSAA; diff --git a/src/index.js b/src/index.js index 524b139..439556c 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,7 @@ * @module redux-api-middleware * @requires isomorphic-fetch * @requires lodash.isplainobject - * @exports {symbol} CALL_API + * @exports {string} RSAA * @exports {function} isRSAA * @exports {function} validateRSAA * @exports {function} isValidRSAA @@ -29,14 +29,14 @@ * @returns undefined */ -import CALL_API from './CALL_API'; +import RSAA from './RSAA'; import { isRSAA, validateRSAA, isValidRSAA } from './validation'; import { InvalidRSAA, InternalError, RequestError, ApiError } from './errors'; import { getJSON } from './util'; import { apiMiddleware } from './middleware'; export { - CALL_API, + RSAA, isRSAA, validateRSAA, isValidRSAA, diff --git a/src/middleware.js b/src/middleware.js index 0df4014..26e3902 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -1,7 +1,7 @@ import fetch from 'isomorphic-fetch'; import isPlainObject from 'lodash.isplainobject'; -import CALL_API from './CALL_API'; +import RSAA from './RSAA'; import { isRSAA, validateRSAA } from './validation'; import { InvalidRSAA, RequestError, ApiError } from './errors' ; import { getJSON, normalizeTypeDescriptors, actionWith } from './util'; @@ -14,7 +14,7 @@ import { getJSON, normalizeTypeDescriptors, actionWith } from './util'; */ function apiMiddleware({ getState }) { return (next) => async (action) => { - // Do not process actions without a [CALL_API] property + // Do not process actions without an [RSAA] property if (!isRSAA(action)) { return next(action); } @@ -22,7 +22,7 @@ function apiMiddleware({ getState }) { // Try to dispatch an error request FSA for invalid RSAAs const validationErrors = validateRSAA(action); if (validationErrors.length) { - const callAPI = action[CALL_API]; + const callAPI = action[RSAA]; if (callAPI.types && Array.isArray(callAPI.types)) { let requestType = callAPI.types[0]; if (requestType && requestType.type) { @@ -38,7 +38,7 @@ function apiMiddleware({ getState }) { } // Parse the validated RSAA action - const callAPI = action[CALL_API]; + const callAPI = action[RSAA]; var { endpoint, headers } = callAPI; const { method, body, credentials, bailout, types } = callAPI; const [requestType, successType, failureType] = normalizeTypeDescriptors(types); @@ -53,14 +53,14 @@ function apiMiddleware({ getState }) { return next(await actionWith( { ...requestType, - payload: new RequestError('[CALL_API].bailout function failed'), + payload: new RequestError('[RSAA].bailout function failed'), error: true }, [action, getState()] )); } - // Process [CALL_API].endpoint function + // Process [RSAA].endpoint function if (typeof endpoint === 'function') { try { endpoint = endpoint(getState()); @@ -68,7 +68,7 @@ function apiMiddleware({ getState }) { return next(await actionWith( { ...requestType, - payload: new RequestError('[CALL_API].endpoint function failed'), + payload: new RequestError('[RSAA].endpoint function failed'), error: true }, [action, getState()] @@ -76,7 +76,7 @@ function apiMiddleware({ getState }) { } } - // Process [CALL_API].headers function + // Process [RSAA].headers function if (typeof headers === 'function') { try { headers = headers(getState()); @@ -84,7 +84,7 @@ function apiMiddleware({ getState }) { return next(await actionWith( { ...requestType, - payload: new RequestError('[CALL_API].headers function failed'), + payload: new RequestError('[RSAA].headers function failed'), error: true }, [action, getState()] diff --git a/src/util.js b/src/util.js index dd83a84..83c447d 100644 --- a/src/util.js +++ b/src/util.js @@ -24,7 +24,7 @@ async function getJSON(res) { * * @function normalizeTypeDescriptors * @access private - * @param {array} types - The [CALL_API].types from a validated RSAA + * @param {array} types - The [RSAA].types from a validated RSAA * @returns {array} */ function normalizeTypeDescriptors(types) { diff --git a/src/validation.js b/src/validation.js index 03ffae5..4c32565 100644 --- a/src/validation.js +++ b/src/validation.js @@ -1,8 +1,8 @@ -import CALL_API from './CALL_API'; +import RSAA from './RSAA'; import isPlainObject from 'lodash.isplainobject'; /** - * Is the given action a plain JavaScript object with a [CALL_API] property? + * Is the given action a plain JavaScript object with an [RSAA] property? * * @function isRSAA * @access public @@ -10,7 +10,7 @@ import isPlainObject from 'lodash.isplainobject'; * @returns {boolean} */ function isRSAA(action) { - return isPlainObject(action) && action.hasOwnProperty(CALL_API); + return isPlainObject(action) && action.hasOwnProperty(RSAA); } /** @@ -81,58 +81,58 @@ function validateRSAA(action) { ] if (!isRSAA(action)) { - validationErrors.push('RSAAs must be plain JavaScript objects with a [CALL_API] property'); + validationErrors.push('RSAAs must be plain JavaScript objects with an [RSAA] property'); return validationErrors; } for (let key in action) { - if (key !== [CALL_API]) { + if (key !== RSAA) { validationErrors.push(`Invalid root key: ${key}`); } } - const callAPI = action[CALL_API]; + const callAPI = action[RSAA]; if (!isPlainObject(callAPI)) { - validationErrors.push('[CALL_API] property must be a plain JavaScript object'); + validationErrors.push('[RSAA] property must be a plain JavaScript object'); } for (let key in callAPI) { if (!~validCallAPIKeys.indexOf(key)) { - validationErrors.push(`Invalid [CALL_API] key: ${key}`); + validationErrors.push(`Invalid [RSAA] key: ${key}`); } } const { endpoint, method, headers, credentials, types, bailout } = callAPI; if (typeof endpoint === 'undefined') { - validationErrors.push('[CALL_API] must have an endpoint property'); + validationErrors.push('[RSAA] must have an endpoint property'); } else if (typeof endpoint !== 'string' && typeof endpoint !== 'function') { - validationErrors.push('[CALL_API].endpoint property must be a string or a function'); + validationErrors.push('[RSAA].endpoint property must be a string or a function'); } if (typeof method === 'undefined') { - validationErrors.push('[CALL_API] must have a method property'); + validationErrors.push('[RSAA] must have a method property'); } else if (typeof method !== 'string') { - validationErrors.push('[CALL_API].method property must be a string'); + validationErrors.push('[RSAA].method property must be a string'); } else if (!~validMethods.indexOf(method.toUpperCase())) { - validationErrors.push(`Invalid [CALL_API].method: ${method.toUpperCase()}`); + validationErrors.push(`Invalid [RSAA].method: ${method.toUpperCase()}`); } if (typeof headers !== 'undefined' && !isPlainObject(headers) && typeof headers !== 'function') { - validationErrors.push('[CALL_API].headers property must be undefined, a plain JavaScript object, or a function'); + validationErrors.push('[RSAA].headers property must be undefined, a plain JavaScript object, or a function'); } if (typeof credentials !== 'undefined') { if (typeof credentials !== 'string') { - validationErrors.push('[CALL_API].credentials property must be undefined, or a string'); + validationErrors.push('[RSAA].credentials property must be undefined, or a string'); } else if (!~validCredentials.indexOf(credentials)) { - validationErrors.push(`Invalid [CALL_API].credentials: ${credentials}`); + validationErrors.push(`Invalid [RSAA].credentials: ${credentials}`); } } if (typeof bailout !== 'undefined' && typeof bailout !== 'boolean' && typeof bailout !== 'function') { - validationErrors.push('[CALL_API].bailout property must be undefined, a boolean, or a function'); + validationErrors.push('[RSAA].bailout property must be undefined, a boolean, or a function'); } if (typeof types === 'undefined') { - validationErrors.push('[CALL_API] must have a types property'); + validationErrors.push('[RSAA] must have a types property'); } else if (!Array.isArray(types) || types.length !== 3) { - validationErrors.push('[CALL_API].types property must be an array of length 3'); + validationErrors.push('[RSAA].types property must be an array of length 3'); } else { const [requestType, successType, failureType] = types; if (typeof requestType !== 'string' && typeof requestType !== 'symbol' && !isValidTypeDescriptor(requestType)) { diff --git a/test/index.js b/test/index.js index 95765ed..a013cb0 100644 --- a/test/index.js +++ b/test/index.js @@ -2,7 +2,7 @@ import test from 'tape'; import { Schema, normalize, arrayOf } from 'normalizr'; import nock from 'nock'; -import CALL_API from '../src/CALL_API'; +import RSAA from '../src/RSAA'; import { isRSAA, isValidTypeDescriptor, validateRSAA, isValidRSAA } from '../src/validation'; import { InvalidRSAA, InternalError, RequestError, ApiError } from '../src/errors'; import { getJSON, normalizeTypeDescriptors, actionWith } from '../src/util'; @@ -18,11 +18,11 @@ test('isRSAA must identify RSAAs', (t) => { const action2 = {}; t.notOk( isRSAA(action2), - 'RSAAs must have a [CALL_API] property' + 'RSAAs must have an [RSAA] property' ); const action3 = { - [CALL_API]: {} + [RSAA]: {} }; t.ok( isRSAA(action3), @@ -85,117 +85,117 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { const action1 = ''; t.ok( validateRSAA(action1).length === 1 && - validateRSAA(action1).includes('RSAAs must be plain JavaScript objects with a [CALL_API] property'), - 'RSAAs must be plain JavaScript objects with a [CALL_API] property (validateRSAA)' + validateRSAA(action1).includes('RSAAs must be plain JavaScript objects with an [RSAA] property'), + 'RSAAs must be plain JavaScript objects with an [RSAA] property (validateRSAA)' ); t.notOk( isValidRSAA(action1), - 'RSAAs must be plain JavaScript objects with a [CALL_API] property (isValidRSAA)' + 'RSAAs must be plain JavaScript objects with an [RSAA] property (isValidRSAA)' ); const action2 = { - [CALL_API]: {}, + [RSAA]: {}, invalidKey: '' }; t.ok( validateRSAA(action2).includes('Invalid root key: invalidKey'), - 'RSAAs must not have properties other than [CALL_API] (validateRSAA)' + 'RSAAs must not have properties other than [RSAA] (validateRSAA)' ); t.notOk( isValidRSAA(action2), - 'RSAAs must not have properties other than [CALL_API] (isValidRSAA)' + 'RSAAs must not have properties other than [RSAA] (isValidRSAA)' ); const action3 = { - [CALL_API]: '' + [RSAA]: '' }; t.ok( - validateRSAA(action3).includes('[CALL_API] property must be a plain JavaScript object'), - '[CALL_API] property must be a plain JavaScript object (validateRSAA)' + validateRSAA(action3).includes('[RSAA] property must be a plain JavaScript object'), + '[RSAA] property must be a plain JavaScript object (validateRSAA)' ); t.notOk( isValidRSAA(action3), - '[CALL_API] property must be a plain JavaScript object (isValidRSAA)' + '[RSAA] property must be a plain JavaScript object (isValidRSAA)' ); const action4 = { - [CALL_API]: { invalidKey: '' } + [RSAA]: { invalidKey: '' } }; t.ok( - validateRSAA(action4).includes('Invalid [CALL_API] key: invalidKey'), - '[CALL_API] must not have properties other than endpoint, method, types, body, headers, credentials, and bailout (validateRSAA)' + validateRSAA(action4).includes('Invalid [RSAA] key: invalidKey'), + '[RSAA] must not have properties other than endpoint, method, types, body, headers, credentials, and bailout (validateRSAA)' ); t.notOk( isValidRSAA(action4), - '[CALL_API] must not have properties other than endpoint, method, types, body, headers, credentials, and bailout (isValidRSAA)' + '[RSAA] must not have properties other than endpoint, method, types, body, headers, credentials, and bailout (isValidRSAA)' ); const action5 = { - [CALL_API]: {} + [RSAA]: {} }; t.ok( validateRSAA(action5).includes( - '[CALL_API] must have an endpoint property', - '[CALL_API] must have a method property', - '[CALL_API] must have a types property' + '[RSAA] must have an endpoint property', + '[RSAA] must have a method property', + '[RSAA] must have a types property' ), - '[CALL_API] must have endpoint, method, and types properties (validateRSAA)' + '[RSAA] must have endpoint, method, and types properties (validateRSAA)' ); t.notOk( isValidRSAA(action5), - '[CALL_API] must have endpoint, method, and types properties (isValidRSAA)' + '[RSAA] must have endpoint, method, and types properties (isValidRSAA)' ); const action6 = { - [CALL_API]: { + [RSAA]: { endpoint: {}, method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'] } }; t.ok( - validateRSAA(action6).includes('[CALL_API].endpoint property must be a string or a function'), - '[CALL_API].endpoint must be a string or a function (validateRSAA)' + validateRSAA(action6).includes('[RSAA].endpoint property must be a string or a function'), + '[RSAA].endpoint must be a string or a function (validateRSAA)' ); t.notOk( isValidRSAA(action6), - '[CALL_API].endpoint must be a string or a function (isValidRSAA)' + '[RSAA].endpoint must be a string or a function (isValidRSAA)' ); const action7 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: {}, types: ['REQUEST', 'SUCCESS', 'FAILURE'] } }; t.ok( - validateRSAA(action7).includes('[CALL_API].method property must be a string'), - '[CALL_API].method property must be a string (validateRSAA)' + validateRSAA(action7).includes('[RSAA].method property must be a string'), + '[RSAA].method property must be a string (validateRSAA)' ); t.notOk( isValidRSAA(action7), - '[CALL_API].method property must be a string (isValidRSAA)' + '[RSAA].method property must be a string (isValidRSAA)' ); const action8 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'InvalidMethod', types: ['REQUEST', 'SUCCESS', 'FAILURE'] } }; t.ok( - validateRSAA(action8).includes('Invalid [CALL_API].method: INVALIDMETHOD'), - '[CALL_API].method must be one of the strings \'GET\', \'HEAD\', \'POST\', \'PUT\', \'PATCH\' \'DELETE\', or \'OPTIONS\' (validateRSAA)' + validateRSAA(action8).includes('Invalid [RSAA].method: INVALIDMETHOD'), + '[RSAA].method must be one of the strings \'GET\', \'HEAD\', \'POST\', \'PUT\', \'PATCH\' \'DELETE\', or \'OPTIONS\' (validateRSAA)' ); t.notOk( isValidRSAA(action8), - '[CALL_API].method must be one of the strings \'GET\', \'HEAD\', \'POST\', \'PUT\', \'PATCH\' \'DELETE\', or \'OPTIONS\' (isValidRSAA)' + '[RSAA].method must be one of the strings \'GET\', \'HEAD\', \'POST\', \'PUT\', \'PATCH\' \'DELETE\', or \'OPTIONS\' (isValidRSAA)' ); const action9 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'], @@ -203,16 +203,16 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { } }; t.ok( - validateRSAA(action9).includes('[CALL_API].headers property must be undefined, a plain JavaScript object, or a function'), - '[CALL_API].headers property must be undefined, a plain JavaScript object, or a function (validateRSAA)' + validateRSAA(action9).includes('[RSAA].headers property must be undefined, a plain JavaScript object, or a function'), + '[RSAA].headers property must be undefined, a plain JavaScript object, or a function (validateRSAA)' ); t.notOk( isValidRSAA(action9), - '[CALL_API].headers property must be undefined, a plain JavaScript object, or a function (isValidRSAA)' + '[RSAA].headers property must be undefined, a plain JavaScript object, or a function (isValidRSAA)' ); const action10 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'], @@ -220,16 +220,16 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { } }; t.ok( - validateRSAA(action10).includes('[CALL_API].credentials property must be undefined, or a string'), - '[CALL_API].credentials property must be undefined or a string (validateRSAA)' + validateRSAA(action10).includes('[RSAA].credentials property must be undefined, or a string'), + '[RSAA].credentials property must be undefined or a string (validateRSAA)' ); t.notOk( isValidRSAA(action10), - '[CALL_API].credentials property must be undefined or a string (isValidRSAA)' + '[RSAA].credentials property must be undefined or a string (isValidRSAA)' ); const action11 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'], @@ -237,16 +237,16 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { } }; t.ok( - validateRSAA(action11).includes('Invalid [CALL_API].credentials: InvalidCredentials'), - '[CALL_API].credentials property must be one of the string \'omit\', \'same-origin\', or \'include\' (validateRSAA)' + validateRSAA(action11).includes('Invalid [RSAA].credentials: InvalidCredentials'), + '[RSAA].credentials property must be one of the string \'omit\', \'same-origin\', or \'include\' (validateRSAA)' ); t.notOk( isValidRSAA(action11), - '[CALL_API].credentials property must be one of the string \'omit\', \'same-origin\', or \'include\' (isValidRSAA)' + '[RSAA].credentials property must be one of the string \'omit\', \'same-origin\', or \'include\' (isValidRSAA)' ); const action12 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'], @@ -254,48 +254,48 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { } }; t.ok( - validateRSAA(action12).includes('[CALL_API].bailout property must be undefined, a boolean, or a function'), - '[CALL_API].bailout must be undefined, a boolean, or a function (validateRSAA)' + validateRSAA(action12).includes('[RSAA].bailout property must be undefined, a boolean, or a function'), + '[RSAA].bailout must be undefined, a boolean, or a function (validateRSAA)' ); t.notOk( isValidRSAA(action12), - '[CALL_API].bailout must be undefined, a boolean, or a function (isValidRSAA)' + '[RSAA].bailout must be undefined, a boolean, or a function (isValidRSAA)' ); const action13 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: {} } }; t.ok( - validateRSAA(action13).includes('[CALL_API].types property must be an array of length 3'), - '[CALL_API].types property must be an array (validateRSAA)' + validateRSAA(action13).includes('[RSAA].types property must be an array of length 3'), + '[RSAA].types property must be an array (validateRSAA)' ); t.notOk( isValidRSAA(action13), - '[CALL_API].types property must be an array (isRSAA)' + '[RSAA].types property must be an array (isRSAA)' ) const action14 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: ['a', 'b'] } }; t.ok( - validateRSAA(action14).includes('[CALL_API].types property must be an array of length 3'), - '[CALL_API].types property must have length 3 (validateRSAA)' + validateRSAA(action14).includes('[RSAA].types property must be an array of length 3'), + '[RSAA].types property must have length 3 (validateRSAA)' ); t.notOk( isValidRSAA(action14), - '[CALL_API].types property must have length 3 (isRSAA)' + '[RSAA].types property must have length 3 (isRSAA)' ) const action15 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: [{}, {}, {}] @@ -307,15 +307,15 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { 'Invalid success type', 'Invalid failure type' ), - 'Each element in [CALL_API].types property must be a string, a symbol, or a type descriptor (validateRSAA)' + 'Each element in [RSAA].types property must be a string, a symbol, or a type descriptor (validateRSAA)' ); t.notOk( isValidRSAA(action15), - 'Each element in [CALL_API].types property must be a string, a symbol, or a type descriptor (isRSAA)' + 'Each element in [RSAA].types property must be a string, a symbol, or a type descriptor (isRSAA)' ) const action16 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'] @@ -324,15 +324,15 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { t.equal( validateRSAA(action16).length, 0, - '[CALL_API].endpoint may be a string (validateRSAA)' + '[RSAA].endpoint may be a string (validateRSAA)' ); t.ok( isValidRSAA(action16), - '[CALL_API].endpoint may be a string (isValidRSAA)' + '[RSAA].endpoint may be a string (isValidRSAA)' ) const action17 = { - [CALL_API]: { + [RSAA]: { endpoint: () => '', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'] @@ -341,15 +341,15 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { t.equal( validateRSAA(action17).length, 0, - '[CALL_API].endpoint may be a function (validateRSAA)' + '[RSAA].endpoint may be a function (validateRSAA)' ); t.ok( isValidRSAA(action17), - '[CALL_API].endpoint may be a function (isValidRSAA)' + '[RSAA].endpoint may be a function (isValidRSAA)' ); const action18 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'], @@ -359,15 +359,15 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { t.equal( validateRSAA(action18).length, 0, - '[CALL_API].headers may be a plain JavaScript object (validateRSAA)' + '[RSAA].headers may be a plain JavaScript object (validateRSAA)' ); t.ok( isValidRSAA(action18), - '[CALL_API].headers may be a plain JavaScript object (isRSAA)' + '[RSAA].headers may be a plain JavaScript object (isRSAA)' ); const action19 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'], @@ -377,15 +377,15 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { t.equal( validateRSAA(action19).length, 0, - '[CALL_API].headers may be a function (validateRSAA)' + '[RSAA].headers may be a function (validateRSAA)' ); t.ok( isValidRSAA(action19), - '[CALL_API].headers may be a function (isRSAA)' + '[RSAA].headers may be a function (isRSAA)' ); const action20 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'], @@ -395,15 +395,15 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { t.equal( validateRSAA(action20).length, 0, - '[CALL_API].bailout may be a boolean (validateRSAA)' + '[RSAA].bailout may be a boolean (validateRSAA)' ); t.ok( isValidRSAA(action20), - '[CALL_API].bailout may be a boolean (isRSAA)' + '[RSAA].bailout may be a boolean (isRSAA)' ); const action21 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'], @@ -413,15 +413,15 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { t.equal( validateRSAA(action21).length, 0, - '[CALL_API].bailout may be a function (validateRSAA)' + '[RSAA].bailout may be a function (validateRSAA)' ); t.ok( isValidRSAA(action21), - '[CALL_API].bailout may be a function (isRSAA)' + '[RSAA].bailout may be a function (isRSAA)' ); const action22 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: [Symbol(), Symbol(), Symbol()] @@ -430,15 +430,15 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { t.equal( validateRSAA(action22).length, 0, - 'Each element in [CALL_API].types may be a symbol (validateRSAA)' + 'Each element in [RSAA].types may be a symbol (validateRSAA)' ); t.ok( isValidRSAA(action22), - 'Each element in [CALL_API].types may be a symbol (isRSAA)' + 'Each element in [RSAA].types may be a symbol (isRSAA)' ); const action23 = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', types: [ @@ -463,11 +463,11 @@ test('validateRSAA/isValidRSAA must identify conformant RSAAs', (t) => { t.equal( validateRSAA(action23).length, 0, - 'Each element in [CALL_API].types may be a type descriptor (validateRSAA)' + 'Each element in [RSAA].types may be a type descriptor (validateRSAA)' ); t.ok( isValidRSAA(action23), - 'Each element in [CALL_API].types may be a type descriptor (isRSAA)' + 'Each element in [RSAA].types may be a type descriptor (isRSAA)' ); t.end(); @@ -837,7 +837,7 @@ test('apiMiddleware must be a Redux middleware', (t) => { t.end(); }); -test('apiMiddleware must pass actions without a [CALL_API] property to the next handler', (t) => { +test('apiMiddleware must pass actions without an [RSAA] property to the next handler', (t) => { const anAction = {}; const doGetState = () => {}; const nextHandler = apiMiddleware({ getState: doGetState }); @@ -857,7 +857,7 @@ test('apiMiddleware must pass actions without a [CALL_API] property to the next test('apiMiddleware must dispatch an error request FSA for an invalid RSAA with a string request type', (t) => { const anAction = { - [CALL_API]: { + [RSAA]: { types: ['REQUEST'] } }; @@ -893,7 +893,7 @@ test('apiMiddleware must dispatch an error request FSA for an invalid RSAA with test('apiMiddleware must dispatch an error request FSA for an invalid RSAA with a descriptor request type', (t) => { const anAction = { - [CALL_API]: { + [RSAA]: { types: [ { type: 'REQUEST' @@ -933,7 +933,7 @@ test('apiMiddleware must dispatch an error request FSA for an invalid RSAA with test('apiMiddleware must do nothing for an invalid RSAA without a request type', (t) => { const anAction = { - [CALL_API]: {} + [RSAA]: {} }; const doGetState = () => {}; const nextHandler = apiMiddleware({ getState: doGetState }); @@ -949,9 +949,9 @@ test('apiMiddleware must do nothing for an invalid RSAA without a request type', }, 200); }); -test('apiMiddleware must dispatch an error request FSA when [CALL_API].bailout fails', (t) => { +test('apiMiddleware must dispatch an error request FSA when [RSAA].bailout fails', (t) => { const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', bailout: () => { throw new Error(); }, @@ -977,7 +977,7 @@ test('apiMiddleware must dispatch an error request FSA when [CALL_API].bailout f ); t.equal( action.payload.message, - '[CALL_API].bailout function failed', + '[RSAA].bailout function failed', 'dispatched FSA has correct payload property' ); t.equal( @@ -996,9 +996,9 @@ test('apiMiddleware must dispatch an error request FSA when [CALL_API].bailout f actionHandler(anAction); }); -test('apiMiddleware must dispatch an error request FSA when [CALL_API].endpoint fails', (t) => { +test('apiMiddleware must dispatch an error request FSA when [RSAA].endpoint fails', (t) => { const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: () => { throw new Error(); }, method: 'GET', types: [ @@ -1023,7 +1023,7 @@ test('apiMiddleware must dispatch an error request FSA when [CALL_API].endpoint ); t.equal( action.payload.message, - '[CALL_API].endpoint function failed', + '[RSAA].endpoint function failed', 'dispatched FSA has correct payload property' ); t.equal( @@ -1042,9 +1042,9 @@ test('apiMiddleware must dispatch an error request FSA when [CALL_API].endpoint actionHandler(anAction); }); -test('apiMiddleware must dispatch an error request FSA when [CALL_API].headers fails', (t) => { +test('apiMiddleware must dispatch an error request FSA when [RSAA].headers fails', (t) => { const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: '', method: 'GET', headers: () => { throw new Error(); }, @@ -1070,7 +1070,7 @@ test('apiMiddleware must dispatch an error request FSA when [CALL_API].headers f ); t.equal( action.payload.message, - '[CALL_API].headers function failed', + '[RSAA].headers function failed', 'dispatched FSA has correct payload property' ); t.equal( @@ -1091,7 +1091,7 @@ test('apiMiddleware must dispatch an error request FSA when [CALL_API].headers f test('apiMiddleware must dispatch an error request FSA on a request error', (t) => { const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: 'http://127.0.0.1/api/users/1', // We haven't mocked this method: 'GET', types: [ @@ -1162,9 +1162,9 @@ test('apiMiddleware must dispatch an error request FSA on a request error', (t) actionHandler(anAction); }); -test('apiMiddleware must use a [CALL_API].bailout boolean when present', (t) => { +test('apiMiddleware must use an [RSAA].bailout boolean when present', (t) => { const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: 'http://127.0.0.1/api/users/1', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'], @@ -1185,14 +1185,14 @@ test('apiMiddleware must use a [CALL_API].bailout boolean when present', (t) => }, 200); }); -test('apiMiddleware must use a [CALL_API].bailout function when present', (t) => { +test('apiMiddleware must use an [RSAA].bailout function when present', (t) => { const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: 'http://127.0.0.1/api/users/1', method: 'GET', types: ['REQUEST', 'SUCCESS', 'FAILURE'], bailout: () => { - t.pass('[CALL_API].bailout function called'); + t.pass('[RSAA].bailout function called'); return true; } } @@ -1208,14 +1208,14 @@ test('apiMiddleware must use a [CALL_API].bailout function when present', (t) => actionHandler(anAction); }); -test('apiMiddleware must use an [CALL_API].endpoint function when present', (t) => { +test('apiMiddleware must use an [RSAA].endpoint function when present', (t) => { const api = nock('http://127.0.0.1') .get('/api/users/1') .reply(200); const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: () => { - t.pass('[CALL_API].endpoint function called'); + t.pass('[RSAA].endpoint function called'); return 'http://127.0.0.1/api/users/1'; }, method: 'GET', @@ -1231,16 +1231,16 @@ test('apiMiddleware must use an [CALL_API].endpoint function when present', (t) actionHandler(anAction); }); -test('apiMiddleware must use an [CALL_API].headers function when present', (t) => { +test('apiMiddleware must use an [RSAA].headers function when present', (t) => { const api = nock('http://127.0.0.1') .get('/api/users/1') .reply(200); const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: 'http://127.0.0.1/api/users/1', method: 'GET', headers: () => { - t.pass('[CALL_API].headers function called') + t.pass('[RSAA].headers function called') }, types: ['REQUEST', 'SUCCESS', 'FAILURE'] } @@ -1259,7 +1259,7 @@ test('apiMiddleware must dispatch a success FSA on a successful API call with a .get('/api/users/1') .reply(200, { username: 'Alice' }, { 'Content-Type': 'application/json' }); const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: 'http://127.0.0.1/api/users/1', method: 'GET', types: [ @@ -1327,7 +1327,7 @@ test('apiMiddleware must dispatch a success FSA on a successful API call with an .get('/api/users/1') .reply(200, {}, { 'Content-Type': 'application/json' }); const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: 'http://127.0.0.1/api/users/1', method: 'GET', types: [ @@ -1395,7 +1395,7 @@ test('apiMiddleware must dispatch a success FSA on a successful API call with a .get('/api/users/1') .reply(200); const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: 'http://127.0.0.1/api/users/1', method: 'GET', types: [ @@ -1464,7 +1464,7 @@ test('apiMiddleware must dispatch a failure FSA on an unsuccessful API call with .get('/api/users/1') .reply(404, { error: 'Resource not found' }, { 'Content-Type': 'application/json' }); const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: 'http://127.0.0.1/api/users/1', method: 'GET', types: [ @@ -1532,7 +1532,7 @@ test('apiMiddleware must dispatch a failure FSA on an unsuccessful API call with .get('/api/users/1') .reply(404, {}, { 'Content-Type': 'application/json' }); const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: 'http://127.0.0.1/api/users/1', method: 'GET', types: [ @@ -1600,7 +1600,7 @@ test('apiMiddleware must dispatch a failure FSA on an unsuccessful API call with .get('/api/users/1') .reply(404); const anAction = { - [CALL_API]: { + [RSAA]: { endpoint: 'http://127.0.0.1/api/users/1', method: 'GET', types: [ From a17b0a8623578ea62030c25d924f3de3cf91460c Mon Sep 17 00:00:00 2001 From: Barry Staes Date: Tue, 8 Mar 2016 09:26:53 +0100 Subject: [PATCH 5/6] Initial v2.0.0-beta commit for `next` branch. --- README.md | 9 ++++++++- package.json | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ad48529..81a95fc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ redux-api-middleware ==================== -[![Build Status](https://travis-ci.org/agraboso/redux-api-middleware.svg?branch=master)](https://travis-ci.org/agraboso/redux-api-middleware) [![Coverage Status](https://coveralls.io/repos/agraboso/redux-api-middleware/badge.svg?branch=master&service=github)](https://coveralls.io/github/agraboso/redux-api-middleware?branch=master) +## This `next` branch is 2.0.0-beta in development! +Aught to be stable but still in development while we iron out bugs. + +[![Build Status](https://travis-ci.org/agraboso/redux-api-middleware.svg?branch=next)](https://travis-ci.org/agraboso/redux-api-middleware) [![Coverage Status](https://coveralls.io/repos/agraboso/redux-api-middleware/badge.svg?branch=next&service=github)](https://coveralls.io/github/agraboso/redux-api-middleware?branch=next) [Redux middleware](http://rackt.github.io/redux/docs/advanced/Middleware.html) for calling an API. @@ -594,6 +597,10 @@ TODO $ npm install && npm test ``` +## Upgrading from v1.0.x + +TODO + ## License MIT diff --git a/package.json b/package.json index 0f37167..88a8d3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redux-api-middleware", - "version": "1.0.0", + "version": "2.0.0-beta.1", "description": "Redux middleware for calling an API.", "main": "lib/index.js", "scripts": { From 47d1d324e6762230f61cf7108138e93bf203cd5d Mon Sep 17 00:00:00 2001 From: Jeff Tribble Date: Tue, 8 Mar 2016 10:45:35 -0700 Subject: [PATCH 6/6] Add estraverse-fb package to fix temp eslint bug (See: https://github.com/eslint/eslint/issues/5476) --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 1bfd1a5..e8886f0 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "coveralls": "^2.11.4", "eslint": "^2.0.0", "eslint-plugin-babel": "^3.1.0", + "estraverse-fb": "^1.3.1", "nock": "^2.15.0", "normalizr": "^1.1.0", "rimraf": "^2.4.3",