Skip to content

Commit ab94c45

Browse files
author
Kelly Wallach
authored
Merge pull request #341 from amplitude/kwallach/msw-add-on
Add support for capturing requests and responses for test data generation
2 parents 358612d + 113997c commit ab94c45

File tree

3 files changed

+99
-8
lines changed

3 files changed

+99
-8
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @flow
2+
3+
export function getCookie(name: string) {
4+
const value = `; ${document.cookie}`;
5+
const parts = value.split(`; ${name}=`);
6+
if (parts.length === 2)
7+
return parts
8+
.pop()
9+
.split(';')
10+
.shift();
11+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// @flow
2+
import type { ResponseBody, RequestBody } from '../types';
3+
import type { HttpMethod } from '../constants/http-methods';
4+
import { getCookie } from './cookie';
5+
6+
type Requests = {
7+
rest: {
8+
[url: string]: {
9+
method: string,
10+
body: ResponseBody,
11+
response: any,
12+
},
13+
},
14+
gql: {
15+
[query: string]: {
16+
response: any,
17+
},
18+
},
19+
};
20+
21+
const createBaseRequests = () => {
22+
return {
23+
rest: {},
24+
gql: {},
25+
};
26+
};
27+
28+
const cookieName = 'redux_query_store_requests_for_test_data';
29+
30+
export class RequestsForTestData {
31+
requests: Requests = createBaseRequests();
32+
33+
constructor() {
34+
if (this.getShouldStoreRequests()) {
35+
window.getRequestsForTestData = this.getRequests;
36+
window.clearRequestsForTestData = this.clearRequests;
37+
}
38+
}
39+
40+
getShouldStoreRequests = () => {
41+
return getCookie(cookieName) === 'true' ? true : false;
42+
};
43+
44+
getRequests = () => {
45+
return this.requests;
46+
};
47+
48+
clearRequests = () => {
49+
this.requests = createBaseRequests();
50+
};
51+
52+
addRequest = (url: string, body: RequestBody, method: HttpMethod, response: any) => {
53+
if (this.getShouldStoreRequests()) {
54+
let query = null;
55+
let restUrl = url;
56+
if (body && body.hasOwnProperty('query')) {
57+
const bodyQuery = body.query;
58+
const firstNonQueryChar =
59+
bodyQuery.indexOf('(') !== -1 ? bodyQuery.indexOf('(') : bodyQuery.indexOf(' {');
60+
query = bodyQuery.slice(6, firstNonQueryChar); // 6 because 'query '
61+
this.requests.gql[query] = {
62+
response,
63+
};
64+
} else {
65+
restUrl = url.indexOf('?') !== -1 ? url.slice(0, url.indexOf('?')) : url;
66+
this.requests.rest[restUrl] = {
67+
method,
68+
body,
69+
response,
70+
};
71+
}
72+
}
73+
};
74+
}

packages/redux-query/src/middleware/query.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,24 @@
33
import Backoff from 'backo';
44

55
import {
6-
requestStart,
7-
requestFailure,
8-
requestSuccess,
9-
mutateStart,
106
mutateFailure,
7+
mutateStart,
118
mutateSuccess,
9+
requestFailure,
10+
requestStart,
11+
requestSuccess,
1212
} from '../actions';
1313
import * as actionTypes from '../constants/action-types';
1414
import httpMethods from '../constants/http-methods';
1515
import * as statusCodes from '../constants/status-codes';
16-
import { getQueryKey } from '../lib/query-key';
17-
import { updateEntities, optimisticUpdateEntities, rollbackEntities } from '../lib/update';
1816
import { pick } from '../lib/object';
17+
import { getQueryKey } from '../lib/query-key';
18+
import { optimisticUpdateEntities, rollbackEntities, updateEntities } from '../lib/update';
19+
import { RequestsForTestData } from '../lib/requestsForTestData';
1920

2021
import type { Action, PublicAction } from '../actions';
22+
import type { State as QueriesState } from '../reducers/queries';
2123
import type {
22-
ActionPromiseValue,
2324
EntitiesSelector,
2425
NetworkHandler,
2526
NetworkInterface,
@@ -29,7 +30,6 @@ import type {
2930
Status,
3031
Transform,
3132
} from '../types';
32-
import type { State as QueriesState } from '../reducers/queries';
3333

3434
type Config = {|
3535
backoff: {|
@@ -101,6 +101,8 @@ const queryMiddleware = (
101101
}
102102
};
103103

104+
const requestsForTestData = new RequestsForTestData();
105+
104106
return ({ dispatch, getState }: ReduxStore) => (next: Next) => (action: PublicAction) => {
105107
let returnValue;
106108
const config = { ...defaultConfig, ...customConfig };
@@ -171,6 +173,8 @@ const queryMiddleware = (
171173
attempts += 1;
172174

173175
networkHandler.execute((err, status, responseBody, responseText, responseHeaders) => {
176+
requestsForTestData.addRequest(url, body, method, responseBody);
177+
174178
if (
175179
config.retryableStatusCodes.includes(status) &&
176180
attempts < config.backoff.maxAttempts
@@ -312,6 +316,8 @@ const queryMiddleware = (
312316
);
313317

314318
networkHandler.execute((err, status, responseBody, responseText, responseHeaders) => {
319+
requestsForTestData.addRequest(url, body, method, responseBody);
320+
315321
const end = new Date();
316322
const duration = end - start;
317323
const state = getState();

0 commit comments

Comments
 (0)