-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathclient.test.js
163 lines (132 loc) · 6.03 KB
/
client.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**
* TODO: test errors, more on merge options and other notable use cases
*/
import {init, call, getClient} from './client'
global.fetch = require('jest-fetch-mock')
const DEFAULT_FOO = '12345'
const DEFAULT_HOST = 'http://test.com'
const TEST_URL = 'users'
const MUSEMENT_HOST = 'https://www.musement.com/api/v3'
const CITIES_URL = 'cities.json'
const DEFAULT_HEADERS = {
'Accept': '*/*',
'Content-Type': 'application/json'
}
const GET_DEFAULT_HEADERS = () => DEFAULT_HEADERS
jest.setTimeout(30000);
const delayed = (body, TIMEOUT) => () => new Promise((resolve, reject) => {
setTimeout(() => resolve({body: JSON.stringify(body)}), TIMEOUT)
})
beforeEach(() => {
fetch.resetMocks()
init(DEFAULT_HOST, GET_DEFAULT_HEADERS)
})
test('simple GET build correctly URL and returns JSON data', () => {
fetch.mockResponseOnce(JSON.stringify({ foo: DEFAULT_FOO }))
return call(TEST_URL, {fullResponse: true})
.then(res => {
expect(res.req.url).toBe(`${DEFAULT_HOST}/${TEST_URL}`)
expect(res.data.foo).toBe(DEFAULT_FOO)
expect(fetch.mock.calls.length).toEqual(1)
expect(fetch.mock.calls[0][0]).toBe(`${DEFAULT_HOST}/${TEST_URL}`)
})
})
test('headers are correctly merged', () => {
fetch.mockResponseOnce(JSON.stringify({ foo: DEFAULT_FOO }))
return call(TEST_URL, {fullResponse: true, headers: {'X-Custom-header': '44'}})
.then(res => {
const {req: {fetchOpt: {headers}}} = res
expect(headers['X-Custom-header']).toBe('44')
Object.keys(DEFAULT_HEADERS).forEach(header =>
expect(headers[header]).toBe(DEFAULT_HEADERS[header])
)
expect(fetch.mock.calls.length).toEqual(1)
expect(fetch.mock.calls[0][0]).toBe(`${DEFAULT_HOST}/${TEST_URL}`)
})
})
test('headers are correctly overridden for single call mergeHeader option', () => {
fetch.mockResponseOnce(JSON.stringify({ foo: DEFAULT_FOO }))
return call(TEST_URL, {fullResponse: true, headers: {'X-Custom-header': '44'}, mergeHeaders: false})
.then(res => {
const {req: {fetchOpt: {headers}}} = res
expect(headers['X-Custom-header']).toBe('44')
expect(Object.keys(headers).length).toBe(1)
expect(fetch.mock.calls.length).toEqual(1)
expect(fetch.mock.calls[0][0]).toBe(`${DEFAULT_HOST}/${TEST_URL}`)
})
})
test('headers are correctly overridden for global mergeHeader option', () => {
fetch.mockResponseOnce(JSON.stringify({ foo: DEFAULT_FOO }))
init(DEFAULT_HOST, GET_DEFAULT_HEADERS, {mergeHeaders: false})
return call(TEST_URL, {fullResponse: true, headers: {'X-Custom-header': '44'}})
.then(res => {
const {req: {fetchOpt: {headers}}} = res
expect(headers['X-Custom-header']).toBe('44')
expect(Object.keys(headers).length).toBe(1)
expect(fetch.mock.calls.length).toEqual(1)
expect(fetch.mock.calls[0][0]).toBe(`${DEFAULT_HOST}/${TEST_URL}`)
})
})
test('get multiple client instances', () => {
fetch.mockResponse(JSON.stringify({ foo: DEFAULT_FOO }))
const SECOND_HOST = 'http://open.com'
const SECOND_HEADERS = {'Language': 'it'}
const call1 = getClient(DEFAULT_HOST, GET_DEFAULT_HEADERS)
const call2 = getClient(SECOND_HOST, () => SECOND_HEADERS)
return call1(TEST_URL, {fullResponse: true})
.then(res => {
const {req: {url, fetchOpt: {headers}}} = res
expect(url).toBe(`${DEFAULT_HOST}/${TEST_URL}`)
expect(headers['Content-Type']).toBe(DEFAULT_HEADERS['Content-Type'])
expect(res.data.foo).toBe(DEFAULT_FOO)
expect(fetch.mock.calls.length).toEqual(1)
expect(fetch.mock.calls[0][0]).toBe(`${DEFAULT_HOST}/${TEST_URL}`)
return call2('customers', {fullResponse: true})
.then(res => {
const {req: {url, fetchOpt: {headers}}} = res
expect(url).toBe(`${SECOND_HOST}/customers`)
expect(headers['Language']).toBe(SECOND_HEADERS['Language'])
expect(res.data.foo).toBe(DEFAULT_FOO)
expect(fetch.mock.calls.length).toEqual(2)
expect(fetch.mock.calls[1][0]).toBe(`${SECOND_HOST}/customers`)
})
})
})
test('timeout occurs and timeout error is raised', async () => {
init(MUSEMENT_HOST, GET_DEFAULT_HEADERS)
fetch.mockResponseOnce(delayed({ foo: DEFAULT_FOO }, 5000))
try {
const res = await call(CITIES_URL, {timeout: 1000, fullResponse: true})
expect(true).toBe(false);
} catch (e) {
expect(e.status).toBe(408)
expect(e.response.statusText).toMatch(/^CLIENT TIMEOUT:/)
expect(fetch.mock.calls.length).toEqual(1)
expect(fetch.mock.calls[0][0]).toBe(`${MUSEMENT_HOST}/${CITIES_URL}`)
}
})
// TODO: to be fixed
test('timeout does not occurs and no error is raised', async () => {
init(MUSEMENT_HOST, GET_DEFAULT_HEADERS)
fetch.mockResponseOnce(delayed({ foo: DEFAULT_FOO }, 1000))
const res = await call(CITIES_URL, {timeout: 2000, fullResponse: true})
expect(res.req.url).toBe(`${MUSEMENT_HOST}/${CITIES_URL}`)
expect(res.data.foo).toBe(DEFAULT_FOO)
expect(fetch.mock.calls.length).toEqual(1)
expect(fetch.mock.calls[0][0]).toBe(`${MUSEMENT_HOST}/${CITIES_URL}`)
})
test('requests with option.blob will result in a Blob object', async () => {
fetch.mockResponseOnce(delayed({ foo: DEFAULT_FOO }, 1000))
init(MUSEMENT_HOST, GET_DEFAULT_HEADERS)
const res = await call('test', {parse: 'blob', body: { test: '12345=' }})
expect(res.constructor.name).toBe('Blob')
})
// test('mocked responses resolve with the given value', async () => {
// init(MUSEMENT_HOST, GET_DEFAULT_HEADERS)
// // fetch.mockReject(new Error('fake error message'))
// // fetch.mockResponseOnce(delayed({ foo: DEFAULT_FOO }, 1000))
//
// const res = await call(CITIES_URL, {mock: {test: 97}})
// console.log('eccc', res)
// expect(res.test).toBe(97)
// })