Skip to content

Commit 9caf4a0

Browse files
authored
[Added] Warn about responses not being used
2 parents 041f059 + 825d1ac commit 9caf4a0

5 files changed

Lines changed: 176 additions & 13 deletions

File tree

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export { wrap } from './wrap'
22
export { mockFetch } from './mockFetch'
3-
export { configureMocks } from './config'
3+
export { configureMocks } from './config'
4+
export { getNotUtilizedResponses } from './notUtilizedResponses'

src/mockFetch.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import deepEqual from 'deep-equal'
22
import { white, redBright, greenBright } from 'chalk'
33
import { getMocksConfig } from './config'
4+
import { saveListOfResponses, addResponseAsUtilized, getNotUtilizedResponses } from './notUtilizedResponses'
45

56
global.fetch = jest.fn()
67

@@ -45,39 +46,44 @@ const createResponse = async ({ responseBody, status = 200, headers }) => (
4546

4647
function mockFetch(responses) {
4748
const listOfResponses = responses.length > 0 ? responses : [ responses ]
49+
saveListOfResponses(listOfResponses)
4850

4951
global.fetch.mockImplementation(async request => {
5052
const normalizedRequestBody = await getNormalizedRequestBody(request)
5153
const responseMatchingRequest = listOfResponses.find(getRequestMatcher(request, normalizedRequestBody))
5254

5355
if (!responseMatchingRequest) {
5456
console.warn(`
55-
${ white.bold.bgRed('burrito') } ${ redBright.bold('cannot find any mock matching:') }
56-
URL: ${ greenBright(request.url) }
57-
METHOD: ${ greenBright(request.method.toLowerCase()) }
58-
REQUEST BODY: ${ greenBright(JSON.stringify(normalizedRequestBody)) }
59-
`)
57+
${ white.bold.bgRed('burrito') } ${ redBright.bold('cannot find any mock matching:') }
58+
59+
URL: ${ greenBright(request.url) }
60+
METHOD: ${ greenBright(request.method.toLowerCase()) }
61+
REQUEST BODY: ${ greenBright(JSON.stringify(normalizedRequestBody)) }
62+
`)
6063
throw Error(redBright.bold('cannot find any mock'))
6164
}
6265

6366
const { multipleResponses } = responseMatchingRequest
6467
if (!multipleResponses) {
68+
addResponseAsUtilized(responseMatchingRequest)
6569
return createResponse(responseMatchingRequest)
6670
}
6771

6872
const responseNotYetReturned = multipleResponses.find(({ hasBeenReturned }) => !hasBeenReturned)
6973
if (!responseNotYetReturned) {
7074
console.warn(`
71-
${ white.bold.bgRed('burrito') } ${ redBright.bold('all responses have been returned already given:') }
72-
URL: ${ greenBright(request.url) }
73-
METHOD: ${ greenBright(request.method.toLowerCase()) }
74-
REQUEST BODY: ${ greenBright(JSON.stringify(normalizedRequestBody)) }
75+
${ white.bold.bgRed('burrito') } ${ redBright.bold('all responses have been returned already given:') }
76+
77+
URL: ${ greenBright(request.url) }
78+
METHOD: ${ greenBright(request.method.toLowerCase()) }
79+
REQUEST BODY: ${ greenBright(JSON.stringify(normalizedRequestBody)) }
7580
`)
7681
throw Error(redBright.bold('all responses for the given request have been returned already'))
7782
}
7883
responseNotYetReturned.hasBeenReturned = true
84+
addResponseAsUtilized(responseMatchingRequest)
7985
return createResponse(responseNotYetReturned)
8086
})
8187
}
8288

83-
export { mockFetch }
89+
export { mockFetch, getNotUtilizedResponses }

src/notUtilizedResponses.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { greenBright, yellow, black } from 'chalk'
2+
3+
let mockedResponses = []
4+
const saveListOfResponses = listOfResponses => mockedResponses = [ ...listOfResponses ]
5+
6+
let utilizedResponses = []
7+
const addResponseAsUtilized = utilizedResponse => utilizedResponses = [ ...utilizedResponses, utilizedResponse ]
8+
9+
const getNotUtilizedResponses = () => {
10+
const notUtilizedResponses = mockedResponses.filter(response => {
11+
const hasNotUtilzedResponses = !utilizedResponses.includes(response)
12+
const multiplResponseNotFullyReturned = response.multipleResponses && response.multipleResponses.some(multipleResponseIsNotUsed)
13+
return hasNotUtilzedResponses || multiplResponseNotFullyReturned
14+
})
15+
16+
const allResponsesAreBeingUtilized = notUtilizedResponses.length === 0
17+
18+
if (allResponsesAreBeingUtilized) return
19+
20+
console.warn(`
21+
${ black.bold.bgYellow('burrito') } ${ yellow.bold('the following responses are not being used:') }
22+
${ notUtilizedResponses.map(({ path, method = 'get', responseBody, multipleResponses }) => `
23+
PATH: ${ greenBright(path) }
24+
METHOD: ${ greenBright(method.toLowerCase()) }
25+
${ getProperResponseBody(responseBody, multipleResponses) }
26+
`)}
27+
`)
28+
}
29+
30+
const getProperResponseBody = (responseBody, multipleResponses) => {
31+
const hasMultipleResponses = multipleResponses && multipleResponses.length > 0
32+
if (hasMultipleResponses) {
33+
return `MULTIPLE RESPONSES:
34+
${ multipleResponses
35+
.filter(multipleResponseIsNotUsed)
36+
.map(response => greenBright(JSON.stringify(response.responseBody))).join(`
37+
`) }
38+
`
39+
}
40+
41+
return `RESPONSE BODY: ${ greenBright(responseBody) }`
42+
}
43+
44+
const multipleResponseIsNotUsed = response => !response.hasBeenReturned
45+
46+
export { saveListOfResponses, addResponseAsUtilized, getNotUtilizedResponses }

tests/notUtilizedResponses.test.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { render, wait, cleanup } from '@testing-library/react'
2+
import { wrap, configureMocks, getNotUtilizedResponses } from '../src/index'
3+
import { MyComponentMakingHttpCalls, MyComponentRepeatingHttpCalls } from './components.mock'
4+
import { refreshProductsList } from './helpers'
5+
6+
configureMocks({ defaultHost: 'my-host', mount: render })
7+
8+
afterEach(() => {
9+
cleanup()
10+
jest.restoreAllMocks()
11+
})
12+
13+
it('should warn when there are responses not being used', async () => {
14+
const consoleWarn = jest.spyOn(console, 'warn').mockImplementation()
15+
16+
wrap(MyComponentMakingHttpCalls)
17+
.withMocks([
18+
{ path: '/path/to/get/quantity/', responseBody: '15' },
19+
{ path: '/path/to/endpoint/not/being/used/', responseBody: 'I am not being used' },
20+
])
21+
.mount()
22+
23+
await wait(() => {
24+
getNotUtilizedResponses()
25+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('the following responses are not being used:'))
26+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('/path/to/endpoint/not/being/used/'))
27+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('get'))
28+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('I am not being used'))
29+
})
30+
})
31+
32+
it('should warn when there are multiple responses not being used', async () => {
33+
const consoleWarn = jest.spyOn(console, 'warn').mockImplementation()
34+
35+
wrap(MyComponentMakingHttpCalls)
36+
.withMocks([
37+
{ path: '/path/to/get/quantity/', responseBody: '15' },
38+
{ path: '/path/to/endpoint/not/being/used/', multipleResponses: [
39+
{ responseBody: { value: 'I will not be used' } },
40+
{ responseBody: { value: 'Me neither' } },
41+
]},
42+
])
43+
.mount()
44+
45+
await wait(() => {
46+
getNotUtilizedResponses()
47+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('the following responses are not being used:'))
48+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('/path/to/endpoint/not/being/used/'))
49+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('get'))
50+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('I will not be used'))
51+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('Me neither'))
52+
})
53+
})
54+
55+
it('should warn when at least one of the multiple responses are not being used', async () => {
56+
const consoleWarn = jest.spyOn(console, 'warn').mockImplementation()
57+
const productsBeforeRefreshing = ['tomato', 'orange']
58+
const productsAfterRefreshing = ['tomato', 'orange', 'apple']
59+
60+
const { container } = wrap(MyComponentRepeatingHttpCalls)
61+
.withMocks({ path: '/path/to/get/products/', multipleResponses: [
62+
{ responseBody: productsBeforeRefreshing },
63+
{ responseBody: productsAfterRefreshing },
64+
]},)
65+
.mount()
66+
67+
refreshProductsList(container)
68+
69+
await wait(() => {
70+
getNotUtilizedResponses()
71+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('the following responses are not being used:'))
72+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('/path/to/get/products/'))
73+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('get'))
74+
expect(consoleWarn).not.toHaveBeenCalledWith(expect.stringContaining(JSON.stringify(productsBeforeRefreshing)))
75+
expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining(JSON.stringify(productsAfterRefreshing)))
76+
})
77+
})
78+
79+
it('should not warn when all the responses are being used', async () => {
80+
const consoleWarn = jest.spyOn(console, 'warn')
81+
82+
wrap(MyComponentMakingHttpCalls)
83+
.withMocks({ path: '/path/to/get/quantity/', responseBody: '15' })
84+
.mount()
85+
86+
await wait(() => {
87+
getNotUtilizedResponses()
88+
expect(consoleWarn).not.toHaveBeenCalled()
89+
})
90+
})
91+
92+
it('should not warn when all the multiple responses are being used', async () => {
93+
const consoleWarn = jest.spyOn(console, 'warn')
94+
const productsBeforeRefreshing = ['tomato', 'orange']
95+
96+
const { container } = wrap(MyComponentRepeatingHttpCalls)
97+
.withMocks({ path: '/path/to/get/products/', multipleResponses: [
98+
{ responseBody: productsBeforeRefreshing },
99+
]},)
100+
.mount()
101+
102+
refreshProductsList(container)
103+
104+
await wait(() => {
105+
getNotUtilizedResponses()
106+
expect(consoleWarn).not.toHaveBeenCalled()
107+
})
108+
})

tests/withMocks.test.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
import { render, wait, fireEvent } from '@testing-library/react'
2-
import { wrap, configureMocks } from '../src/index'
1+
import { render, wait, fireEvent, cleanup } from '@testing-library/react'
2+
import { wrap, configureMocks, getNotUtilizedResponses } from '../src/index'
33
import { MyComponentMakingHttpCalls, MyComponentRepeatingHttpCalls, } from './components.mock'
44
import { refreshProductsList, getTableRowsText } from './helpers'
55
import { getMocksConfig } from '../src/config'
66

77
const defaultMocksConfig = getMocksConfig()
88

99
function resetMocksConfig() {
10+
cleanup()
1011
configureMocks(defaultMocksConfig)
1112
jest.restoreAllMocks()
13+
getNotUtilizedResponses()
1214
}
1315

1416
afterEach(resetMocksConfig)

0 commit comments

Comments
 (0)