diff --git a/docs/docs/@fetch-mock/core/CallHistory.md b/docs/docs/@fetch-mock/core/CallHistory.md new file mode 100644 index 00000000..62a46780 --- /dev/null +++ b/docs/docs/@fetch-mock/core/CallHistory.md @@ -0,0 +1,93 @@ +--- +sidebar_position: 4 +--- + +# Call history + +`fetchMock.callHistory` is an object used to record the history of all calls handled by `fetchMock.fetchHandler`. + +## CallLog schema + +Calls are recorded, and returned, in a standard format with the following properties: + +- `{string} url` - The url being fetched +- `{NormalizedRequestOptions} options` - The options passed in to the fetch (may be derived from a `Request` if one was used) +- `{Request} [request]` - The `Request` passed to fetch, if one was used +- `{Route} [route]` - The route used to handle the request +- `{Response} [response]` - The `Response` returned to the user +- `{Promise[]} pendingPromises` - An internal structure used by the `.flush()` method documented below + +## Filtering + +Most of `fetchMock.callHistory`'s methods take two arguments — `(filter, options)` — which allow `fetch` calls to be extracted and examined. + +### filter + +Filter calls to `fetch` using one of the following criteria: + +#### undefined + +Retrieve all calls made to `fetch` + +#### true / "matched" + +Retrieve all calls to `fetch` matched by some route defined by `fetch-mock`. The string `'matched'` can be used instead of `true` to make tests more readable + +#### false / "unmatched" + +Retrieve all calls to `fetch` not matched by some route defined by `fetch-mock`, i.e. calls that are handled by `.catch()`. The string `'unmatched'` can be used instead of `false` to make tests more readable + +#### name + +`{String}` + +Retrieve all calls to `fetch` matched by a particular named route. + +#### matcher + +`{String|RegExp|function|Object}` +Any matcher compatible with the [route api](#api-mockingmock_matcher) can be passed in to filter the calls arbitrarily. + +### options + +`{Object}` + +An options object compatible with the [route api](#api-mockingmock_options) to be used to filter the list of calls further. + +## Methods + +`fetchMock.callHistory` exposes the following methods. + +### .recordCall(callLog) + +For internal use. + +### .calls(filter, options) + +Returns an array of all calls matching the given `filter` and `options`. Each call is returned as a `CallLog`. + +### .called(filter, options) + +Returns a Boolean indicating whether any calls to `fetch` matched the given `filter` and `options` + +### .lastCall(filter, options) + +Returns the `CallLog` for the last call to `fetch` matching the given `filter` and `options`. + +### fetchMock.done(routeNames) + +_Note that this function is exposed on the `fetchMock` object, not on `fetchMock.callHistory`_ + +TODO, should callHistory just have access to `routes`... yes probably as these docs are horrible + +Returns a Boolean indicating whether `fetch` was called the expected number of times (or has been called at least once if `repeat` is not defined for the route). It does not take into account whether the `fetches` completed successfully. + +A single name or an array of names can be passed in the `routeNames` parameter to check only certain routes. If no routeNames are passed it runs over all routes. + +### .flush(waitForResponseMethods) + +Returns a `Promise` that resolves once all fetches handled by fetch-mock have resolved + +Useful for testing code that uses `fetch` but where the returned promise cannot be accessed from your tests. + +If `waitForBody` is `true`, the promise will wait for all body parsing methods (`res.json()`, `res.text()`, etc.) to resolve too. diff --git a/docs/docs/@fetch-mock/core/configuration.md b/docs/docs/@fetch-mock/core/configuration.md new file mode 100644 index 00000000..925c8e63 --- /dev/null +++ b/docs/docs/@fetch-mock/core/configuration.md @@ -0,0 +1,52 @@ +--- +sidebar_position: 6 +--- + +# Configuration + +On any `fetch-mock` instance, set configuration options directly on the `fetchMock.config` object. e.g. + +```js +const fetchMock = require('fetch-mock'); +fetchMock.config.sendAsJson = false; +``` + +## Available options + +Options marked with a `†` can also be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the `options` parameter + +### sendAsJson + +`{Boolean}` default: `true` + +Always convert objects passed to `.mock()` to JSON strings before building reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of `ArrayBuffer`s. When `true` the `Content-Type: application/json` header will also be set on each response. + +### includeContentLength + +`{Boolean}` default: `true` + +Sets a `Content-Length` header on each response. + +### matchPartialBody + +`{Boolean}` default: `false` + +Match calls that only partially match a specified body json. Uses the [is-subset](https://www.npmjs.com/package/is-subset) library under the hood, which implements behaviour the same as jest's [.objectContaining()](https://jestjs.io/docs/en/expect#expectobjectcontainingobject) method. + +### Custom fetch implementations + +`fetch`, `Headers`, `Request`, `Response` can all be set on the configuration object, allowing fetch-mock to mock any implementation of `fetch`, e.g. `node-fetch`. e.g. + +```js + +import { default as fetch, Headers, Request, Response } from 'node-fetch'; + +import fetchMock from 'fetch-mock'; + +fetchMock.config = Object.assign(fetchMock.config, { + Request, + Response, + Headers, + fetch, +}); +``` diff --git a/docs/docs/@fetch-mock/core/fetchHandler.md b/docs/docs/@fetch-mock/core/fetchHandler.md new file mode 100644 index 00000000..64b01b29 --- /dev/null +++ b/docs/docs/@fetch-mock/core/fetchHandler.md @@ -0,0 +1,14 @@ +--- +sidebar_position: 1 +sidebar_label: .fetchHandler +--- + +# fetchHandler + +`fetchMock.fetchHandler(url, requestInit)` + +A mock implementation of `fetch`. + +By default it will error. In order to return responses `.route()`, `.catch()` and other convenience methods of `fetchMock` must first be used to add routes to its internal router. + +All calls made using `fetchMock.fetchHandler` are recorded in `fetchMock.callHistory`. diff --git a/docs/docs/@fetch-mock/core/index.md b/docs/docs/@fetch-mock/core/index.md new file mode 100644 index 00000000..101d9976 --- /dev/null +++ b/docs/docs/@fetch-mock/core/index.md @@ -0,0 +1,14 @@ +--- +sidebar_label: '@fetch-mock/core' +sidebar_position: 1 +--- + +# @fetch-mock/core + +This library implements three main features + +1. A function, `fetchHandler`, that can be used as a drop in replacement for fetch. +2. A set of chainable API methods for adding routes to `fetchHandler`, which alter how it handles different requests. +3. Some low level APIs for accessing the call history of `fetchHandler` (these are not intended for direct use by the developer, but expose enough information for other libraries, such as `@fetch-mock/jest`, to provide more user friendly APIs built on top of this low level functionality). + +`@fetch-mock/core` is not intended for direct use in tests. It **DOES NOT** actually replace your `fetch` implementation with `fetchHandler`; this is left to wrapper libraries such as `@fetch-mock/jest`. This is because different testing frameworks have different opinions about this behaviour, and this core library deliberately avoids making decisions likely to clash with other tools in your testing toolchain, so that the `fetchHandler` implementation is more portable. diff --git a/docs/docs/@fetch-mock/core/more-routing-methods.md b/docs/docs/@fetch-mock/core/more-routing-methods.md new file mode 100644 index 00000000..c3795db6 --- /dev/null +++ b/docs/docs/@fetch-mock/core/more-routing-methods.md @@ -0,0 +1,139 @@ +--- +sidebar_position: 3 +sidebar_label: More routing methods +--- + +# More routing methods + +These methods allow defining routes for common use cases while avoiding writing hard to read configuration objects. Unless noted otherwise, each of the methods below have the same signature as `.route()` + +## .catch() + +`.catch(response)` + +Specifies how to respond to calls to `fetch` that don't match any routes. + +It accepts any [response](#api-mockingmock_response) compatible with `.route()`. If no argument is passed, then every unmatched call will receive a `200` response. + +## .sticky() + +Shorthand for `mock()` which creates a route that persists even when `restore()`, `reset()` or `resetbehavior()` are called; + +This method is particularly useful for setting up fixtures that must remain in place for all tests, e.g. + +```js +fetchMock.sticky(/config-hub.com/, require('./fixtures/start-up-config.json')); +``` + +## .once() + +Shorthand for `mock()` which creates a route that can only mock a single request. (see `repeat` option above) + +## .any() + +`.any(response, options)` + +Shorthand for `mock()` which creates a route that will return a response to any fetch request. + +## .anyOnce(response, options) + +`.anyOnce(response, options)` + +Creates a route that responds to any single request + +## .get(), .post(), .put(), .delete(), .head(), .patch() + +Shorthands for `mock()` that create routes that only respond to requests using a particular http method. + +If you use some other method a lot you can easily define your own shorthands e.g. + +```javascript +fetchMock.purge = function (matcher, response, options) { + return this.mock( + matcher, + response, + Object.assign({}, options, { method: 'PURGE' }), + ); +}; +``` + +## .getOnce(), .postOnce(), .putOnce(), .deleteOnce(), .headOnce(), .patchOnce() + +Creates a route that only responds to a single request using a particular http method + +## .getAny(), .postAny(), .putAny(), .deleteAny(), .headAny(), .patchAny() + +`.___Any(response, options)` + +Creates a route that responds to any requests using a particular http method. + +## .getAnyOnce(), .postAnyOnce(), .putAnyOnce(), .deleteAnyOnce(), .headAnyOnce(), .patchAnyOnce() + +`.___AnyOnce(response, options)` + +Creates a route that responds to any single request using a particular http method. + +## .addMatcher(options) + +Allows adding your own, reusable custom matchers to fetch-mock, for example a matcher for interacting with GraphQL queries, or an `isAuthorized` matcher that encapsulates the exact authorization conditions for the API you are mocking, and only requires a `true` or `false` to be input + +### Options + +#### name + +`{String}` + +The name of your matcher. This will be the name of the property used to hold any input to your matcher. e.g. `graphqlVariables` + +#### usesBody + +`{Boolean}` + +If your matcher requires access to the body of the request set this to true; because body can, in some cases, only be accessed by fetch-mock asynchronously, you will need to provide this hint in order to make sure the correct code paths are followed. + +#### matcher + +`{Function}` + +A function which takes a route definition object as input, and returns a function of the signature `(url, options, request) => Boolean`. See the examples below for more detail. The function is passed the fetchMock instance as a second parameter in case you need to access any config. + +##### Examples + +###### Authorization + +```js +fetchMock + .addMatcher({ + name: 'isAuthorized', + matcher: + ({ isAuthorized }) => + (url, options) => { + const actuallyIsAuthorized = options.headers && options.headers.auth; + return isAuthorized ? actuallyIsAuthorized : !actuallyIsAuthorized; + }, + }) + .mock({ isAuthorized: true }, 200) + .mock({ isAuthorized: false }, 401); +``` + +###### GraphQL + +```js +fetchMock + .addMatcher({ + name: 'graphqlVariables', + matcher: ({graphqlVariables}) => (url, options) => { + if (!/\/graphql$/.test(url)) { + return false; + } + const body = JSON.parse(options.body) + return body.variables && Object.keys(body.variables).length === Object.keys(body.graphqlVariables).length && Object.entries(graphqlVariables).every(([key, val]) => body.variables[key] === val) + } + }) + .mock({graphqlVariables: {owner: 'wheresrhys'}}, {data: {account: { + name: 'wheresrhys', + repos: [ ... ] + }}}) +``` + +One intent behind this functionality is to allow companies or publishers of particular toolsets to provide packages that extend fetch-mock to provide a more user friendly experience for developers using fetch to interact with their APIs. The GraphQL use case is a good example of this - the things which a developer might want to match on are buried in the request body, and written in a non-javascript query language. Please get in touch if you'd like to collaborate on writing such a package. diff --git a/docs/docs/@fetch-mock/core/resetting.md b/docs/docs/@fetch-mock/core/resetting.md new file mode 100644 index 00000000..98072f32 --- /dev/null +++ b/docs/docs/@fetch-mock/core/resetting.md @@ -0,0 +1,47 @@ +--- +sidebar_position: 5 +--- + +# Resetting + +The methods below can be used to restore some or all of fetchMock's behaviour toits default state. + +## .removeRoutes(options) + +This method removes some or all of the routes that have been added to fetch mock. It accepts the following options. + +### names + +An array of named routes to remove. If no value is passed then all routes compatible with the other options passed are removed. + +### includeSticky + +A boolean indicating whether or not to remove sticky routes. + +### includeFallback + +A boolean indicating whether or not to remove the fallback route (added using `.catch()`) + +## .clearHistory() + +Clears all data recorded for `fetch`'s calls. + +## .createInstance() + +Can be used to create a standalone instance of fetch mock that is completely independent of other instances. + +In older environments - where `fetch` was not a global and test files often ran in a shared process - this was very useful for increasing parallelisation. But in more modern setups - global `fetch` and isolated processes per test file - it's less relevant. + +It can however be used as an alternative to `fetchMock.removeRoutes().clearHistory()` by creating a completely new fetchMock instance and swapping this for the previously used one. + +It can also be used to "fork" a previous instance as routes are cloned from one instance to another. However call history is always reset for new instances. + +```js +fetchMock.route('http://my.site', 200); +fetchMock.fetchHandler('http://my.site'); + +const newFM = fetchMock.createInstance(); + +newFM.routes.routes; // Array[1] +newFM.callHistory.calls(); // Array[0] +``` diff --git a/docs/docs/@fetch-mock/core/route/_category_.json b/docs/docs/@fetch-mock/core/route/_category_.json new file mode 100644 index 00000000..98a74b37 --- /dev/null +++ b/docs/docs/@fetch-mock/core/route/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 2.5, + "collapsible": false, + "collapsed": false, +} diff --git a/docs/docs/@fetch-mock/core/route/index.md b/docs/docs/@fetch-mock/core/route/index.md new file mode 100644 index 00000000..f24f0d48 --- /dev/null +++ b/docs/docs/@fetch-mock/core/route/index.md @@ -0,0 +1,135 @@ +--- +sidebar_position: 2 +sidebar_label: .route() +--- + +# route() + +`fetchMock.route(matcher, response, options)` + +Adds a route to `fetchHandler`'s router. A route is a combination of + +- one or more rules for deciding whether a particular fetch request should be handled by the route +- configuration for generating an appropriate response + +## Parameters + +### matcher + +`{String|Regex|Function|Object}` + +Determines which calls to `fetch` should be handled by this route. If multiple criteria need to be applied at once, e.g. matching headers and a uirl pattern, then an object containing multiple matchers may be used. + +### response + +`{String|Object|Function|Promise|Response}` + +Response to send when a call is matched + +### options + +`{Object|String}` + +More options to configure matching and response behaviour. Alternatively, when a `String` is provided it will be used as a name for the route (used when inspecting calls or removing routes). + +## Alternate call patterns + +As well as the function signature described above, the following patterns are supported. + +### Name as third parameter + +A string can be passed as the third parameter, and will be used as the route name. e.g. +`fetchMock.route('*', 200, 'catch-all')` is equivalent to `fetchMock.route('*', 200, {name: 'catch-all'})`. + +### Matchers on third parameter + +The matchers specified in the first parameter are merged internally with the options object passed as the third parameter. This means that it does not matter on which of these objects you specify options/matchers. + +This can be particularly useful for clearly and concisely expressing similar routes that only differ in e.g. different query strings or headers e.g. + +```js +fetchMock + .route('http://my.site', 401) + .route('http://my.site', 200, { headers: { auth: true } }); +``` + +### Single options object + +Matchers, options and a response can be combined on a single options object passed into the first parameter, e.g. + +```js +fetchMock.route({ + url: 'http://my.site', + repeat: 2 + response: 200 +}) + +``` + +## Examples + +### Strings + +```js +fetchMock + .route('http://it.at.here/route', 200) + .route('begin:http://it', 200) + .route('end:here/route', 200) + .route('path:/route', 200) + .route('*', 200); +``` + +### Complex Matchers + +```js +fetchMock + .route(/.*\.here.*/, 200) + .route((url, opts) => opts.method === 'patch', 200) + .route('express:/:type/:id', 200, { + params: { + type: 'shoe', + }, + }) + .route( + { + headers: { Authorization: 'Bearer 123' }, + method: 'POST', + }, + 200, + ); +``` + +### Responses + +```js +fetchMock + .route('*', 'ok') + .route('*', 404) + .route('*', {results: []}) + .route('*', {throw: new Error('Bad kitty'))) + .route('*', new Promise(res => setTimeout(res, 1000, 404))) + .route('*', (url, opts) => { + status: 302, + headers: { + Location: url.replace(/^http/, 'https') + }, + })) +``` + +### End to end example + +```js +fetchMock.route('begin:http://it.at.here/api', 403).route( + { + url: 'begin:http://it.at.here/api', + headers: { + authorization: 'Basic dummy-token', + }, + }, + 200, +); + +callApi('/endpoint', 'dummy-token').then((res) => { + expect(res.status).to.equal(200); +}); +``` diff --git a/docs/docs/@fetch-mock/core/route/matcher.md b/docs/docs/@fetch-mock/core/route/matcher.md new file mode 100644 index 00000000..4f5c1b2f --- /dev/null +++ b/docs/docs/@fetch-mock/core/route/matcher.md @@ -0,0 +1,142 @@ +--- +sidebar_position: 1 +--- + +# matcher + +Determines whether a route should be used to generate a response for a request. + +URL matchers and function matchers can be passed in as standalone values. They can also be combined with other matchers by passing in an object containing one or more matchers. e.g. + +```js +{ + url: "begin: https://my.site", + method: 'post' +} +``` + +## URL matchers + +All of the following can be passed in directly as the `matcher` argument or as the property `{url: ...}` when combining with other matchers or options. + +> Note that if using a Full url matcher or `end:`, fetch-mock ([for good reason](https://url.spec.whatwg.org/#url-equivalence)) is unable to distinguish whether URLs without a path end in a trailing slash or not i.e. `http://thing` is treated the same as `http://thing/` + +### Full url + +`{String|URL}` +Match an exact url. Can be defined using a string or a `URL` instance, e.g. `"http://www.site.com/page.html"` + +The value `*` can be used to match any url + +### begin:... + +`{String}` +Match a url beginning with a string, e.g. `"begin:http://www.site.com"` + +### end:... + +`{String}` +Match a url ending with a string, e.g. `"end:.jpg"` + +### path:... + +`{String}` +Match a url which has a given path, e.g. `"path:/posts/2018/7/3"` + +### glob:... + +`{String}` +Match a url using a glob pattern, e.g. `"glob:http://*.*"` + +### RegExp + +`{RegExp}` +Matches a url that satisfies a regular expression, e.g. `/(article|post)\/\d+/` + +### express:... + +`{String}` +Match a url that satisfies an [express style path](https://www.npmjs.com/package/path-to-regexp), e.g. `"express:/user/:user"` + +#### Matching express param values + +`{Object}` + +When the `express:` keyword is used in a string matcher, it can be combined with the `{params: ...}` matcher to match only requests whose express parameters evaluate to certain values. e.g. + +``` +{ + express: "/:section/user/:user", + params: {"section": "feed", "user": "geoff"} +} +``` + +## Other matching criteria + +### method + +`{String}` + +Match only requests using this http method. Not case-sensitive, e.g. `{method: "get"}`, `{method: "POST"}` + +### headers + +`{Object|Headers}` + +Match only requests that have these headers set, e.g. `{headers: {"Accepts": "text/html"}}` + +### query + +`{Object}` + +Match only requests that have these query parameters set (in any order). Query parameters are matched by using Node.js [querystring](https://nodejs.org/api/querystring.html) module. In summary the bahaviour is as follows + +- strings, numbers and booleans are coerced to strings +- arrays of values are coerced to repetitions of the key +- all other values, including `undefined`, are coerced to an empty string + The request will be matched whichever order keys appear in the query string. + Any query parameters sent in the request which are not included in the keys of the object provided will be ignored. + +#### Examples + +- `{{query: "q": "cute+kittenz"}}` `?q=cute kittenz` or `?q=cute+kittenz` or `?q=cute+kittenz&mode=big` +- `{{query: "tags": ["cute", "kittenz"]}}` `?tags=cute&tags=kittenz` +- `{{query: "q": undefined, inform: true}}` `?q=&inform=true` + +### body + +`{Object}` + +Match only requests that send a JSON body with the exact structure and properties as the one provided here. + +Note that if matching on body _and_ using `Request` instances in your source code, this forces fetch-mock into an asynchronous flow _before_ it is able to route requests effectively. This means no [inspection methods](#api-inspectionfundamentals) can be used synchronously. You must first either await the fetches to resolve, or `await fetchMock.flush()`. The popular library [Ky](https://github.com/sindresorhus/ky) uses `Request` instances internally, and so also triggers this mode. + +e.g.`{body: { "key1": "value1", "key2": "value2" }}` + +#### matchPartialBody + +`{Boolean}` + +When matching a body, this option ignores any properties not mentioned in the matcher e.g. the following will ignore any properties of body that are not `"key1"`, and will therefore match the body `{ "key1": "value1", "key2": "value2" }`. + +``` +{ + body: { "key1": "value1"}, + matchPartialBody: true +} +``` + +This option can also be [set in the global configuration](/fetch-mock/docs/@fetch-mock/core/configuration) + +## Function matchers + +`{Function(url, option, [Request]): {Boolean}}` + +For use cases not covered by all the built in matchers, a custom function can be used. It should return `true` to indicate a route should respond to a request. It will be passed the `url` and `options` `fetch` was called with. If `fetch` was called with a `Request` instance, it will be passed `url` and `options` inferred from the `Request` instance, with the original `Request` available as a third argument. + +As well as being passed as a standalone argument, it can also be added to the matcher object as the property `{functionMatcher: ...}` when combining with other matchers or options. + +### Examples + +- `(url, {headers}) => !!headers.Authorization` +- `(_, _, request) => !!request.headers.get('Authorization')` diff --git a/docs/docs/@fetch-mock/core/route/options.md b/docs/docs/@fetch-mock/core/route/options.md new file mode 100644 index 00000000..40daafca --- /dev/null +++ b/docs/docs/@fetch-mock/core/route/options.md @@ -0,0 +1,49 @@ +--- +sidebar_position: 3 +--- + +# options + +An object containing further options for configuring mocking behaviour. + +## Options + +### name + +`{String}` + +A unique string naming the route. Used to subsequently retrieve references to the calls handled by it. Only needed for advanced use cases. + +### response + +When using pattern 3. above, `response` can be passed as a property on the options object. See the [response documentation](#usageapimock_response) for valid values. + +### repeat + +`{Int}` + +Limits the number of times the route will be used to respond. If the route has already been called `repeat` times, the call to `fetch()` will fall through to be handled by any other routes defined (which may eventually result in an error if nothing matches it). + +### delay + +`{Int}` + +Delays responding for the number of milliseconds specified. + +### sticky + +`{Boolean}` + +Avoids a route being removed when `removeRoutes()` is called. + +### sendAsJson + +`{Boolean}` + +See [global configuration](#usageconfiguration) + +### includeContentLength + +`{Boolean}` + +See [global configuration](#usageconfiguration) diff --git a/docs/docs/@fetch-mock/core/route/response.md b/docs/docs/@fetch-mock/core/route/response.md new file mode 100644 index 00000000..444da0ea --- /dev/null +++ b/docs/docs/@fetch-mock/core/route/response.md @@ -0,0 +1,84 @@ +--- +sidebar_position: 2 +--- + +# response + +Configures the http response returned by `fetchHandler`. Unless otherwise stated, all responses have a `200` status + +## Response + +`{Response}` + +A [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response) instance to return unaltered. + +## Status code + +`{Int}` + +Returns a `Response` with the given status code, e.g. `200`. The response's `statusText` will also be set to the [default value corresponding to the status](https://fetch.spec.whatwg.org/#dom-response-statustext). + +## String + +`{String}` + +Returns a 200 `Response` with the string as the response body e.g. `"..."` + +## Response config + +`{Object}` + +If the object _only_ contains properties from among those listed below it is used to configure a `Response` to return. + +### body + +`{String|Object}` + +Set the `Response` body, e.g. `"Server responded ok"`, `{ token: 'abcdef' }`. See the `Object` section of the docs below for behaviour when passed an `Object`. + +### status + +`{Int}` + +Sets the `Response` status e.g. `200` + +### headers + +`{Object}` + +Sets the `Response` headers, e.g `{'Content-Type': 'text/html'}` + +### redirectUrl + +`{String}` + +Sets the url from which the `Response` should claim to originate (to imitate followed directs). Will also set `redirected: true` on the response + +### throws + +`{Error}` + +Forces `fetch` to return a `Promise` rejected with the value of `throws` e.g. `new TypeError('Failed to fetch')` + +## Object + +`{Object|ArrayBuffer|...` + +If the `sendAsJson` option is set to `true`, any object that does not match the schema for a response config will be converted to a `JSON` string and set as the response `body`. Otherwise, the object will be set as the response `body` (useful for `ArrayBuffer`s etc.) + +## Promise + +`{Promise}` + +A `Promise` that resolves to any of the options documented above e.g. `new Promise(res => setTimeout(() => res(200), 50))` + +## Function + +`{Function}` + +A function that returns any of the options documented above (including `Promise`. The function will be passed the `url` and `options` `fetch` was called with. If `fetch` was called with a `Request` instance, it will be passed `url` and `options` inferred from the `Request` instance, with the original `Request` passed as a third argument. + +### Examples + +- `(url, opts) => opts.headers.Authorization ? 200 : 403` +- `(_, _, request) => request.headers.get('Authorization') ? 200 : 403` diff --git a/docs/docs/@fetch-mock/index.md b/docs/docs/@fetch-mock/index.md new file mode 100644 index 00000000..3034cd27 --- /dev/null +++ b/docs/docs/@fetch-mock/index.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 0 +--- + +# @fetch-mock suite + +This is a new, work in progress suite of libraries intended to replace fetch-mock. diff --git a/docs/docs/fetch-mock/API/Inspection/done.md b/docs/docs/fetch-mock/API/Inspection/done.md index 8313e526..e419de5b 100644 --- a/docs/docs/fetch-mock/API/Inspection/done.md +++ b/docs/docs/fetch-mock/API/Inspection/done.md @@ -1,9 +1,8 @@ --- sidebar_position: 2 - --- -# .done(filter) +# .done(filter) Returns a Boolean indicating whether `fetch` was called the expected number of times (or has been called at least once if `repeat` is undefined for the route). It does not take into account whether the `fetches` completed successfully. diff --git a/docs/docs/fetch-mock/API/Inspection/flush.md b/docs/docs/fetch-mock/API/Inspection/flush.md index 84172eef..a99f79dd 100644 --- a/docs/docs/fetch-mock/API/Inspection/flush.md +++ b/docs/docs/fetch-mock/API/Inspection/flush.md @@ -1,9 +1,8 @@ --- - sidebar_position: 3 --- -# .flush(waitForBody) +# .flush(waitForBody) Returns a `Promise` that resolves once all fetches handled by fetch-mock have resolved diff --git a/docs/docs/fetch-mock/API/Inspection/inspecting-calls.md b/docs/docs/fetch-mock/API/Inspection/inspecting-calls.md index 160aa7aa..634eb4f3 100644 --- a/docs/docs/fetch-mock/API/Inspection/inspecting-calls.md +++ b/docs/docs/fetch-mock/API/Inspection/inspecting-calls.md @@ -1,10 +1,9 @@ --- - sidebar_position: 1 tableOfContents: maxHeadingLevel: 5 - --- + # Inspecting calls ## Methods diff --git a/docs/docs/fetch-mock/API/Lifecycle/resetting.md b/docs/docs/fetch-mock/API/Lifecycle/resetting.md index 234b93a4..41bb048f 100644 --- a/docs/docs/fetch-mock/API/Lifecycle/resetting.md +++ b/docs/docs/fetch-mock/API/Lifecycle/resetting.md @@ -1,9 +1,8 @@ --- - sidebar_position: 2 --- -# Resetting +# Resetting ## .restore() / .reset() diff --git a/docs/docs/fetch-mock/API/Lifecycle/sandbox.md b/docs/docs/fetch-mock/API/Lifecycle/sandbox.md index 83a891dc..a1bd8687 100644 --- a/docs/docs/fetch-mock/API/Lifecycle/sandbox.md +++ b/docs/docs/fetch-mock/API/Lifecycle/sandbox.md @@ -1,8 +1,7 @@ --- - sidebar_position: 1 - --- + # .sandbox() Returns a function that can be used as a drop-in replacement for `fetch`. Pass this into your mocking library of choice. The function returned by `sandbox()` has all the methods of `fetch-mock` exposed on it and maintains its own state independent of other instances, so tests can be run in parallel. diff --git a/docs/docs/fetch-mock/API/Mocking/Parameters/matcher.md b/docs/docs/fetch-mock/API/Mocking/Parameters/matcher.md index ee07e00d..8bbf78c3 100644 --- a/docs/docs/fetch-mock/API/Mocking/Parameters/matcher.md +++ b/docs/docs/fetch-mock/API/Mocking/Parameters/matcher.md @@ -1,6 +1,7 @@ --- sidebar_position: 1 --- + # matcher Criteria for deciding which requests to mock. @@ -74,7 +75,6 @@ The url and function matchers described above can be combined with other criteri In particular, **headers**, **query string parameters**, **request bodies** and **express parameter values** can all be used as matching criteria. - #### Examples - `{url: 'end:/user/profile', headers: {Authorization: 'Basic 123'}}` diff --git a/docs/docs/fetch-mock/API/Mocking/Parameters/options.md b/docs/docs/fetch-mock/API/Mocking/Parameters/options.md index d9c374cf..ee378c47 100644 --- a/docs/docs/fetch-mock/API/Mocking/Parameters/options.md +++ b/docs/docs/fetch-mock/API/Mocking/Parameters/options.md @@ -1,8 +1,7 @@ --- - sidebar_position: 3 - --- + # optionsOrName Either diff --git a/docs/docs/fetch-mock/API/Mocking/Parameters/response.md b/docs/docs/fetch-mock/API/Mocking/Parameters/response.md index 2b1e5580..839107c2 100644 --- a/docs/docs/fetch-mock/API/Mocking/Parameters/response.md +++ b/docs/docs/fetch-mock/API/Mocking/Parameters/response.md @@ -1,8 +1,7 @@ --- - sidebar_position: 2 - --- + # response Configures the http response returned by the mock. Accepts any of the following values or a `Promise` for any of them (useful when testing race conditions, loading transitions etc.). Unless otherwise stated, all responses have a `200` status diff --git a/docs/docs/fetch-mock/API/Mocking/add-matcher.md b/docs/docs/fetch-mock/API/Mocking/add-matcher.md index d8f40e61..086e70b8 100644 --- a/docs/docs/fetch-mock/API/Mocking/add-matcher.md +++ b/docs/docs/fetch-mock/API/Mocking/add-matcher.md @@ -1,8 +1,8 @@ --- sidebar_position: 3 --- -# .addMatcher(options) +# .addMatcher(options) Allows adding your own, reusable custom matchers to fetch-mock, for example a matcher for interacting with GraphQL queries, or an `isAuthorized` matcher that encapsulates the exact authorization conditions for the API you are mocking, and only requires a `true` or `false` to be input diff --git a/docs/docs/fetch-mock/API/Mocking/catch.md b/docs/docs/fetch-mock/API/Mocking/catch.md index e6d884a2..efb6b12b 100644 --- a/docs/docs/fetch-mock/API/Mocking/catch.md +++ b/docs/docs/fetch-mock/API/Mocking/catch.md @@ -1,8 +1,7 @@ --- - sidebar_position: 3 - --- + # .catch(response) Specifies how to respond to calls to `fetch` that don't match any mocks. diff --git a/docs/docs/fetch-mock/API/Mocking/mock.md b/docs/docs/fetch-mock/API/Mocking/mock.md index 7de5b93f..fe71455c 100644 --- a/docs/docs/fetch-mock/API/Mocking/mock.md +++ b/docs/docs/fetch-mock/API/Mocking/mock.md @@ -1,8 +1,7 @@ --- - sidebar_position: 1 - --- + # .mock(matcher, response, optionsOrName) Initialises or extends a stub implementation of fetch, applying a `route` that matches `matcher`, delivers a `Response` configured using `response`, and that respects the additional `options`. The stub will record its calls so they can be inspected later. If `.mock` is called on the top level `fetch-mock` instance, this stub function will also replace `fetch` globally. Calling `.mock()` with no arguments will carry out this stubbing without defining any mock responses. diff --git a/docs/docs/fetch-mock/API/Mocking/shorthands.md b/docs/docs/fetch-mock/API/Mocking/shorthands.md index e59680db..2660320a 100644 --- a/docs/docs/fetch-mock/API/Mocking/shorthands.md +++ b/docs/docs/fetch-mock/API/Mocking/shorthands.md @@ -1,9 +1,8 @@ --- sidebar_position: 2 - --- -# Shorthand methods +# Shorthand methods These methods allow configuring routes for common use cases while avoiding writing configuration objects. Unless noted otherwise, each of the methods below have the same signature as `.mock(matcher, response, optionsOrName)` diff --git a/docs/docs/fetch-mock/API/Mocking/spy.md b/docs/docs/fetch-mock/API/Mocking/spy.md index 975a9c43..c3318eea 100644 --- a/docs/docs/fetch-mock/API/Mocking/spy.md +++ b/docs/docs/fetch-mock/API/Mocking/spy.md @@ -1,8 +1,7 @@ --- - sidebar_position: 4 - --- + # .spy(matcher) Records call history while passing each call on to `fetch` to be handled by the network. Optionally pass in a `matcher` to scope this to only matched calls, e.g. to fetch a specific resource from the network. diff --git a/docs/docs/fetch-mock/Troubleshooting/cookies.md b/docs/docs/fetch-mock/Troubleshooting/cookies.md index 544db39f..7ef727e2 100644 --- a/docs/docs/fetch-mock/Troubleshooting/cookies.md +++ b/docs/docs/fetch-mock/Troubleshooting/cookies.md @@ -1,8 +1,7 @@ --- - sidebar_position: 5 - --- + # Setting cookies in the browser The `Set-Cookie` header is used to set cookies in the browser. This behaviour is part of the [browser/http spec](https://tools.ietf.org/html/rfc6265#section-4.1), not the fetch spec. As fetch-mock prevents requests getting out of js and into the browser, `Set-Cookie` will have no effect. diff --git a/docs/docs/fetch-mock/Troubleshooting/custom-classes.md b/docs/docs/fetch-mock/Troubleshooting/custom-classes.md index bec1bfaf..b8766258 100644 --- a/docs/docs/fetch-mock/Troubleshooting/custom-classes.md +++ b/docs/docs/fetch-mock/Troubleshooting/custom-classes.md @@ -1,9 +1,8 @@ --- sidebar_position: 4 - --- -# Custom fetch implementation +# Custom fetch implementation `fetch-mock` uses `Request`, `Response` and `Headers` constructors internally, and obtains these from `node-fetch` in Node.js, or `window` in the browser. If you are using an alternative implementation of `fetch` you will need to configure `fetch-mock` to use its implementations of these constructors instead. These should be set on the `fetchMock.config` object, e.g. diff --git a/docs/docs/fetch-mock/Troubleshooting/debug-mode.md b/docs/docs/fetch-mock/Troubleshooting/debug-mode.md index 4b9a9290..dd17b0e1 100644 --- a/docs/docs/fetch-mock/Troubleshooting/debug-mode.md +++ b/docs/docs/fetch-mock/Troubleshooting/debug-mode.md @@ -1,9 +1,8 @@ --- sidebar_position: 5 - --- -# Debugging +# Debugging The first step when debugging tests should be to run with the environment variable `DEBUG=fetch-mock*`. This will output additional logs for debugging purposes. diff --git a/docs/docs/fetch-mock/Troubleshooting/global-non-global.md b/docs/docs/fetch-mock/Troubleshooting/global-non-global.md index be576843..060fce49 100644 --- a/docs/docs/fetch-mock/Troubleshooting/global-non-global.md +++ b/docs/docs/fetch-mock/Troubleshooting/global-non-global.md @@ -1,9 +1,8 @@ --- sidebar_position: 1 - --- -# Global or non-global +# Global or non-global `fetch` can be used by your code globally or locally. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` diff --git a/docs/docs/fetch-mock/Troubleshooting/importing.md b/docs/docs/fetch-mock/Troubleshooting/importing.md index d79a65c9..e846426c 100644 --- a/docs/docs/fetch-mock/Troubleshooting/importing.md +++ b/docs/docs/fetch-mock/Troubleshooting/importing.md @@ -1,9 +1,8 @@ --- sidebar_position: 2 - --- -# Importing the correct version +# Importing the correct version _Note that the documentation below applies to version 9 and below._ diff --git a/docs/docs/fetch-mock/Troubleshooting/troubleshooting.md b/docs/docs/fetch-mock/Troubleshooting/troubleshooting.md index 40272a04..f94b2bd4 100644 --- a/docs/docs/fetch-mock/Troubleshooting/troubleshooting.md +++ b/docs/docs/fetch-mock/Troubleshooting/troubleshooting.md @@ -1,9 +1,8 @@ --- sidebar_position: 1 - --- -# Troubleshooting +# Troubleshooting The first step when debugging tests should be to run with the environment variable `DEBUG=fetch-mock*`. This will output additional logs for debugging purposes. diff --git a/docs/docs/fetch-mock/Usage/Usage.md b/docs/docs/fetch-mock/Usage/Usage.md index 203ec614..2fd4da2f 100644 --- a/docs/docs/fetch-mock/Usage/Usage.md +++ b/docs/docs/fetch-mock/Usage/Usage.md @@ -1,7 +1,6 @@ --- - - --- + fetch-mock is the most comprehensive library for mocking the fetch API. It allows mocking http requests made using [fetch](https://fetch.spec.whatwg.org/) or a library imitating its api, such as [node-fetch](https://www.npmjs.com/package/node-fetch). diff --git a/docs/docs/fetch-mock/Usage/cheatsheet.md b/docs/docs/fetch-mock/Usage/cheatsheet.md index 94158060..dba1a15c 100644 --- a/docs/docs/fetch-mock/Usage/cheatsheet.md +++ b/docs/docs/fetch-mock/Usage/cheatsheet.md @@ -1,9 +1,8 @@ --- sidebar_position: 3 - --- -# Cheatsheet +# Cheatsheet - [Installation](#installation) - [Set up and teardown](#setup-and-teardown) diff --git a/docs/docs/fetch-mock/Usage/configuration.md b/docs/docs/fetch-mock/Usage/configuration.md index 4853d944..abdf0f4a 100644 --- a/docs/docs/fetch-mock/Usage/configuration.md +++ b/docs/docs/fetch-mock/Usage/configuration.md @@ -1,9 +1,8 @@ --- - sidebar_position: 4 --- -# Configuration +# Configuration On any `fetch-mock` instance, set configuration options directly on the `fetchMock.config` object. e.g. diff --git a/docs/docs/fetch-mock/Usage/installation.md b/docs/docs/fetch-mock/Usage/installation.md index bac01a8b..3d1fb14a 100644 --- a/docs/docs/fetch-mock/Usage/installation.md +++ b/docs/docs/fetch-mock/Usage/installation.md @@ -1,9 +1,8 @@ --- sidebar_position: 1 - --- -# Installation +# Installation Install fetch-mock using diff --git a/docs/docs/fetch-mock/Usage/quickstart.md b/docs/docs/fetch-mock/Usage/quickstart.md index 4da778e7..a13b2abc 100644 --- a/docs/docs/fetch-mock/Usage/quickstart.md +++ b/docs/docs/fetch-mock/Usage/quickstart.md @@ -1,9 +1,8 @@ --- - sidebar_position: 2 --- -# Quickstart +# Quickstart ## Setting up your mock diff --git a/docs/docs/fetch-mock/Usage/requirements.md b/docs/docs/fetch-mock/Usage/requirements.md index 35fb6d61..fec4d157 100644 --- a/docs/docs/fetch-mock/Usage/requirements.md +++ b/docs/docs/fetch-mock/Usage/requirements.md @@ -1,9 +1,8 @@ --- sidebar_position: 0.5 - --- -# Requirements +# Requirements fetch-mock requires the following to run: diff --git a/docs/docs/fetch-mock/Usage/versions.md b/docs/docs/fetch-mock/Usage/versions.md index 531a9421..d2096448 100644 --- a/docs/docs/fetch-mock/Usage/versions.md +++ b/docs/docs/fetch-mock/Usage/versions.md @@ -1,6 +1,7 @@ --- sidebar_position: 5 --- + # Versions ### Version 10 @@ -19,7 +20,7 @@ I intend to keep version 10 and above r4easonably clean, with as few workarounds ### Version 9 and below -v7, v8 & v9 are practically identical, only differing in their treatment of a few edge cases, or in compatibility with other libraries and environments. +v7, v8 & v9 are practically identical, only differing in their treatment of a few edge cases, or in compatibility with other libraries and environments. For previous versions follow the documentation below: diff --git a/docs/docs/intro.md b/docs/docs/intro.md deleted file mode 100644 index 45e8604c..00000000 --- a/docs/docs/intro.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Tutorial Intro - -Let's discover **Docusaurus in less than 5 minutes**. - -## Getting Started - -Get started by **creating a new site**. - -Or **try Docusaurus immediately** with **[docusaurus.new](https://docusaurus.new)**. - -### What you'll need - -- [Node.js](https://nodejs.org/en/download/) version 18.0 or above: - - When installing Node.js, you are recommended to check all checkboxes related to dependencies. - -## Generate a new site - -Generate a new Docusaurus site using the **classic template**. - -The classic template will automatically be added to your project after you run the command: - -```bash -npm init docusaurus@latest my-website classic -``` - -You can type this command into Command Prompt, Powershell, Terminal, or any other integrated terminal of your code editor. - -The command also installs all necessary dependencies you need to run Docusaurus. - -## Start your site - -Run the development server: - -```bash -cd my-website -npm run start -``` - -The `cd` command changes the directory you're working with. In order to work with your newly created Docusaurus site, you'll need to navigate the terminal there. - -The `npm run start` command builds your website locally and serves it through a development server, ready for you to view at http://localhost:3000/. - -Open `docs/intro.md` (this page) and edit some lines: the site **reloads automatically** and displays your changes. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 2ce83d70..02d997e6 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -60,7 +60,14 @@ const config = { type: 'docSidebar', sidebarId: 'fetchMockSidebar', position: 'left', - label: 'Docs', + label: 'fetch-mock docs', + }, + { + type: 'docSidebar', + sidebarId: 'suiteSidebar', + position: 'left', + label: '@fetch-mock docs', + className: 'new', }, { href: 'https://github.com/wheresrhys/fetch-mock', diff --git a/docs/sidebars.js b/docs/sidebars.js index 23f524dd..e76a1fb7 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -16,19 +16,7 @@ const sidebars = { // By default, Docusaurus generates a sidebar from the docs folder structure // tutorialSidebar: [{ type: 'autogenerated', dirName: 'tutorial' }], fetchMockSidebar: [{ type: 'autogenerated', dirName: 'fetch-mock' }], - - // But you can create a sidebar manually - /* - tutorialSidebar: [ - 'intro', - 'hello', - { - type: 'category', - label: 'Tutorial', - items: ['tutorial-basics/create-a-document'], - }, - ], - */ + suiteSidebar: [{ type: 'autogenerated', dirName: '@fetch-mock' }], }; export default sidebars; diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 2bc6a4cf..81ce6700 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -28,3 +28,14 @@ --ifm-color-primary-lightest: #4fddbf; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); } + + +a.navbar__link.new::after { + content: '(experimental)'; + display: inline-block; + padding-left: 3px; + color: green; + vertical-align: super; + font-size: 0.8em; + +} diff --git a/docs/src/pages/markdown-page.md b/docs/src/pages/markdown-page.md deleted file mode 100644 index 9756c5b6..00000000 --- a/docs/src/pages/markdown-page.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Markdown page example ---- - -# Markdown page example - -You don't need React to write simple standalone pages.