|
3 | 3 | httpClientPlugin, |
4 | 4 | setDefaultConfig, |
5 | 5 | getDefaultTransformers, |
| 6 | + transformHeaders, |
6 | 7 | } from '../index'; |
7 | 8 |
|
8 | 9 | describe('createWidget method with http client plugin', () => { |
@@ -96,6 +97,9 @@ describe('createWidget method with http client plugin', () => { |
96 | 97 | { |
97 | 98 | "transformResponse": [Function], |
98 | 99 | }, |
| 100 | + { |
| 101 | + "transformRequest": [Function], |
| 102 | + }, |
99 | 103 | { |
100 | 104 | "transformRequest": [Function], |
101 | 105 | "transformResponse": [Function], |
@@ -234,6 +238,95 @@ describe('createWidget method with http client plugin', () => { |
234 | 238 | expect(request.body).toMatchInlineSnapshot(`"{"a":"b"}"`); |
235 | 239 | }); |
236 | 240 |
|
| 241 | + it('should set default Content-Type application/json for POST with body', async () => { |
| 242 | + const { request } = await widget.http.request({ |
| 243 | + method: 'POST', |
| 244 | + path: '/path', |
| 245 | + body: { a: 'b' }, |
| 246 | + headers: {}, |
| 247 | + }); |
| 248 | + |
| 249 | + expect(request.headers.get('Content-Type')).toBe('application/json'); |
| 250 | + expect(request.body).toMatchInlineSnapshot(`"{"a":"b"}"`); |
| 251 | + }); |
| 252 | + |
| 253 | + it('should not override explicit Content-Type when body is present', async () => { |
| 254 | + const { request } = await widget.http.request({ |
| 255 | + method: 'POST', |
| 256 | + path: '/path', |
| 257 | + body: 'raw text', |
| 258 | + headers: { |
| 259 | + 'Content-Type': 'text/plain', |
| 260 | + }, |
| 261 | + }); |
| 262 | + |
| 263 | + expect(request.headers.get('Content-Type')).toBe('text/plain'); |
| 264 | + expect(request.body).toBe('raw text'); |
| 265 | + }); |
| 266 | + |
| 267 | + it('should not set default Content-Type for GET with body', async () => { |
| 268 | + const { request } = await widget.http.request({ |
| 269 | + method: 'GET', |
| 270 | + path: '/path', |
| 271 | + body: { a: 'b' }, |
| 272 | + headers: {}, |
| 273 | + }); |
| 274 | + |
| 275 | + expect(request.headers.get('Content-Type')).toBeNull(); |
| 276 | + }); |
| 277 | + |
| 278 | + it('should set default Content-Type when headers is a Headers instance', async () => { |
| 279 | + const { request } = await widget.http.request({ |
| 280 | + method: 'POST', |
| 281 | + path: '/path', |
| 282 | + body: { a: 'b' }, |
| 283 | + headers: new Headers(), |
| 284 | + }); |
| 285 | + |
| 286 | + expect(request.headers.get('Content-Type')).toBe('application/json'); |
| 287 | + expect(request.body).toMatchInlineSnapshot(`"{"a":"b"}"`); |
| 288 | + }); |
| 289 | + |
| 290 | + it('should serialize body when headers is a Headers instance with Content-Type', async () => { |
| 291 | + const { request } = await widget.http.request({ |
| 292 | + method: 'POST', |
| 293 | + path: '/path', |
| 294 | + body: { a: 'b' }, |
| 295 | + headers: new Headers({ 'Content-Type': 'application/json' }), |
| 296 | + }); |
| 297 | + |
| 298 | + expect(request.headers.get('content-type')).toBe('application/json'); |
| 299 | + expect(request.body).toMatchInlineSnapshot(`"{"a":"b"}"`); |
| 300 | + }); |
| 301 | + |
| 302 | + it('should not override Content-Type when headers is a Headers instance with custom type', async () => { |
| 303 | + const { request } = await widget.http.request({ |
| 304 | + method: 'POST', |
| 305 | + path: '/path', |
| 306 | + body: 'raw', |
| 307 | + headers: new Headers({ 'Content-Type': 'text/plain' }), |
| 308 | + }); |
| 309 | + |
| 310 | + expect(request.headers.get('content-type')).toBe('text/plain'); |
| 311 | + expect(request.body).toBe('raw'); |
| 312 | + }); |
| 313 | + |
| 314 | + it('should preserve existing entries when headers is a Headers instance', async () => { |
| 315 | + const { request } = await widget.http.request({ |
| 316 | + method: 'POST', |
| 317 | + path: '/path', |
| 318 | + body: { a: 'b' }, |
| 319 | + headers: new Headers({ |
| 320 | + Authorization: 'Bearer token', |
| 321 | + 'X-Request-ID': '42', |
| 322 | + }), |
| 323 | + }); |
| 324 | + |
| 325 | + expect(request.headers.get('Authorization')).toBe('Bearer token'); |
| 326 | + expect(request.headers.get('X-Request-ID')).toBe('42'); |
| 327 | + expect(request.headers.get('Content-Type')).toBe('application/json'); |
| 328 | + }); |
| 329 | + |
237 | 330 | it('should timeout request which exceed predefined timeout limit', async () => { |
238 | 331 | widget.$dependencies.fetch = jest.fn((url, request) => { |
239 | 332 | return new Promise((resolve, reject) => { |
@@ -426,3 +519,52 @@ describe('createWidget method with http client plugin', () => { |
426 | 519 | }); |
427 | 520 | }); |
428 | 521 | }); |
| 522 | + |
| 523 | +describe('transformHeaders', () => { |
| 524 | + const transformer = transformHeaders(); |
| 525 | + |
| 526 | + it('should normalize a plain object to a Headers instance', async () => { |
| 527 | + const [result] = await transformer.transformRequest( |
| 528 | + null, |
| 529 | + { headers: { Authorization: 'Bearer token' } }, |
| 530 | + null, |
| 531 | + ); |
| 532 | + |
| 533 | + expect(result.headers).toBeInstanceOf(Headers); |
| 534 | + expect(result.headers.get('Authorization')).toBe('Bearer token'); |
| 535 | + }); |
| 536 | + |
| 537 | + it('should normalize a Headers instance to a new Headers instance', async () => { |
| 538 | + const input = new Headers({ 'X-Custom': 'value' }); |
| 539 | + const [result] = await transformer.transformRequest( |
| 540 | + null, |
| 541 | + { headers: input }, |
| 542 | + null, |
| 543 | + ); |
| 544 | + |
| 545 | + expect(result.headers).toBeInstanceOf(Headers); |
| 546 | + expect(result.headers.get('X-Custom')).toBe('value'); |
| 547 | + }); |
| 548 | + |
| 549 | + it('should normalize null headers to an empty Headers instance', async () => { |
| 550 | + const [result] = await transformer.transformRequest( |
| 551 | + null, |
| 552 | + { headers: null }, |
| 553 | + null, |
| 554 | + ); |
| 555 | + |
| 556 | + expect(result.headers).toBeInstanceOf(Headers); |
| 557 | + expect([...result.headers.entries()]).toHaveLength(0); |
| 558 | + }); |
| 559 | + |
| 560 | + it('should preserve the response unchanged', async () => { |
| 561 | + const response = { ok: true }; |
| 562 | + const [, resultResponse] = await transformer.transformRequest( |
| 563 | + null, |
| 564 | + { headers: {} }, |
| 565 | + response, |
| 566 | + ); |
| 567 | + |
| 568 | + expect(resultResponse).toBe(response); |
| 569 | + }); |
| 570 | +}); |
0 commit comments