Skip to content

Commit 226f9fc

Browse files
authored
feat(classic): Add remaining HTTP method shortcuts: put(), patch(), head(), options(), del() (#107)
Adds the a shortcut method for the remaining standard HTTP methods.
1 parent 7ec2ebf commit 226f9fc

File tree

2 files changed

+194
-9
lines changed

2 files changed

+194
-9
lines changed

packages/classic/src/read/__tests__/http.js

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,152 @@ describe('http', () => {
104104
})
105105
})
106106

107-
describe('execute', () => {
107+
describe('HTTP methods', () => {
108+
beforeEach(() => {
109+
fetch.resetMocks()
110+
fetch.mockResponseOnce(JSON.stringify({ data: '12345' }))
111+
})
112+
113+
describe('execute/get', () => {
114+
test('just an uri', async () => {
115+
await http.execute('http://example.com')
116+
117+
expect(fetch).toHaveBeenCalledWith(
118+
'http://example.com',
119+
expect.objectContaining({
120+
method: 'GET',
121+
})
122+
)
123+
})
124+
125+
test('specifying a method', async () => {
126+
await http.execute('http://example.com', { method: 'HEAD' })
127+
128+
expect(fetch).toHaveBeenCalledWith(
129+
'http://example.com',
130+
expect.objectContaining({
131+
method: 'HEAD',
132+
})
133+
)
134+
})
135+
136+
test('extra headers', async () => {
137+
await http.execute('http://example.com', {
138+
headers: { 'Cache-Control': 'max-age=200' },
139+
})
140+
141+
expect(fetch).toHaveBeenCalledWith(
142+
'http://example.com',
143+
expect.objectContaining({
144+
method: 'GET',
145+
})
146+
)
147+
148+
expect(fetch.mock.calls[0][1].headers.get('Cache-Control')).toEqual(
149+
'max-age=200'
150+
)
151+
})
152+
153+
test('revalidate option', async () => {
154+
await http.execute('http://example.com', {
155+
revalidate: true,
156+
headers: { Agent: 'x' },
157+
})
158+
159+
expect(fetch).toHaveBeenCalledWith(
160+
'http://example.com',
161+
expect.objectContaining({
162+
method: 'GET',
163+
})
164+
)
165+
166+
const headers = fetch.mock.calls[0][1].headers
167+
168+
expect(headers.get('Cache-Control')).toEqual('max-age=0')
169+
expect(headers.get('Agent')).toEqual('x')
170+
})
171+
172+
test('OK response', async () => {
173+
const response = await http.execute('http://example.com')
174+
175+
expect(http.isResponse(response)).toBeTruthy()
176+
expect(http.isOK(response)).toBeTruthy()
177+
expect(response.value.toJS()).toEqual({ data: '12345' })
178+
})
179+
180+
test('Failed response', async () => {
181+
fetch.resetMocks()
182+
fetch.mockResponseOnce(JSON.stringify({}), { status: 404 })
183+
184+
const response = await http.execute('http://example.com')
185+
186+
expect(http.isResponse(response)).toBeTruthy()
187+
expect(http.isOK(response)).not.toBeTruthy()
188+
expect(response.meta).toMatchObject({
189+
status: 404,
190+
message: 'Not Found',
191+
})
192+
})
193+
})
194+
195+
describe('post/put/patch', () => {
196+
test('post', async () => {
197+
for (const m of ['post', 'put', 'patch']) {
198+
fetch.resetMocks()
199+
fetch.mockResponseOnce(JSON.stringify({ data: '12345' }))
200+
201+
// eslint-disable-next-line import/namespace
202+
await http[m].call(
203+
http,
204+
'http://example.com',
205+
{ test: 1 },
206+
{
207+
headers: { Agent: 'x' },
208+
foo: 'bar',
209+
}
210+
)
211+
212+
expect(fetch).toHaveBeenCalledWith(
213+
'http://example.com',
214+
expect.objectContaining({
215+
method: m.toUpperCase(),
216+
foo: 'bar',
217+
body: JSON.stringify({ test: 1 }),
218+
})
219+
)
220+
221+
const headers = fetch.mock.calls[0][1].headers
222+
expect(headers.get('Agent')).toEqual('x')
223+
}
224+
})
225+
})
226+
227+
describe('options/head/delete', async () => {
228+
for (const m of ['options', 'head', 'delete']) {
229+
fetch.resetMocks()
230+
fetch.mockResponseOnce(JSON.stringify({ data: '12345' }))
231+
232+
// eslint-disable-next-line import/namespace
233+
await http[m].call(http, 'http://example.com', {
234+
headers: { Agent: 'x' },
235+
foo: 'bar',
236+
})
237+
238+
expect(fetch).toHaveBeenCalledWith(
239+
'http://example.com',
240+
expect.objectContaining({
241+
method: m.toUpperCase(),
242+
foo: 'bar',
243+
})
244+
)
245+
246+
const headers = fetch.mock.calls[0][1].headers
247+
expect(headers.get('Agent')).toEqual('x')
248+
}
249+
})
250+
108251
test('faild http call returns 998 as status code', async () => {
252+
fetch.resetMocks()
109253
fetch.mockReject()
110254

111255
const response = await http.get('http://example.com')

packages/classic/src/read/http.js

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,63 @@ export function execute(url, options) {
3939
export function post(url, json, options) {
4040
const opts = {
4141
...options,
42+
...jsonBody(json, options),
4243
method: 'POST',
44+
}
45+
return execute(url, opts)
46+
}
47+
48+
export const get = execute
49+
export const httpRead = get
50+
51+
export function options(uri, opts) {
52+
return execute(uri, {
53+
...opts,
54+
method: 'OPTIONS',
55+
})
56+
}
57+
58+
export function del(uri, opts) {
59+
return execute(uri, {
60+
...opts,
61+
method: 'DELETE',
62+
})
63+
}
64+
65+
export function head(uri, opts) {
66+
return execute(uri, {
67+
...opts,
68+
method: 'HEAD',
69+
})
70+
}
71+
72+
export function put(uri, json, options) {
73+
const opts = {
74+
...options,
75+
...jsonBody(json, options),
76+
method: 'PUT',
77+
}
78+
return execute(uri, opts)
79+
}
80+
81+
export function patch(uri, json, options) {
82+
const opts = {
83+
...options,
84+
...jsonBody(json, options),
85+
method: 'PATCH',
86+
}
87+
return execute(uri, opts)
88+
}
89+
90+
function jsonBody(json, options) {
91+
return {
4392
body: JSON.stringify(json),
4493
headers: {
4594
...R.defaultTo({}, R.prop('headers', options)),
4695
'Content-Type': 'application/json',
4796
},
4897
}
49-
return execute(url, {
50-
...opts,
51-
method: 'POST',
52-
})
5398
}
54-
55-
export const get = execute
56-
export const httpRead = get
57-
5899
function processFetchResponse(resp) {
59100
if (resp.ok) {
60101
return resp

0 commit comments

Comments
 (0)