|
1 | 1 | import { createSlice } from '@reduxjs/toolkit' |
2 | | -import { createApi, FetchArgs, fetchBaseQuery } from '@reduxjs/toolkit/query' |
| 2 | +import type { FetchArgs } from '@reduxjs/toolkit/query' |
| 3 | +import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query' |
3 | 4 | import { headersToObject } from 'headers-polyfill' |
4 | 5 | import { HttpResponse, delay, http } from 'msw' |
5 | 6 | // @ts-ignore |
@@ -1255,6 +1256,122 @@ describe('FormData', () => { |
1255 | 1256 | }) |
1256 | 1257 | }) |
1257 | 1258 |
|
| 1259 | +describe('Accept header handling', () => { |
| 1260 | + test('sets Accept header to application/json for json responseHandler', async () => { |
| 1261 | + let request: any |
| 1262 | + ;({ data: request } = await baseQuery( |
| 1263 | + { url: '/echo', responseHandler: 'json' }, |
| 1264 | + commonBaseQueryApi, |
| 1265 | + {}, |
| 1266 | + )) |
| 1267 | + |
| 1268 | + expect(request.headers['accept']).toBe('application/json') |
| 1269 | + }) |
| 1270 | + |
| 1271 | + test('sets Accept header to application/json by default (json is default responseHandler)', async () => { |
| 1272 | + let request: any |
| 1273 | + ;({ data: request } = await baseQuery( |
| 1274 | + { url: '/echo' }, |
| 1275 | + commonBaseQueryApi, |
| 1276 | + {}, |
| 1277 | + )) |
| 1278 | + |
| 1279 | + expect(request.headers['accept']).toBe('application/json') |
| 1280 | + }) |
| 1281 | + |
| 1282 | + test('sets Accept header for text responseHandler', async () => { |
| 1283 | + // Create a baseQuery with text as the global responseHandler |
| 1284 | + const textBaseQuery = fetchBaseQuery({ |
| 1285 | + baseUrl, |
| 1286 | + fetchFn: fetchFn as any, |
| 1287 | + responseHandler: 'text', |
| 1288 | + }) |
| 1289 | + |
| 1290 | + let request: any |
| 1291 | + // Override to json just for this test so we can inspect the echoed request object |
| 1292 | + ;({ data: request } = await textBaseQuery( |
| 1293 | + { url: '/echo', responseHandler: 'json' }, |
| 1294 | + commonBaseQueryApi, |
| 1295 | + {}, |
| 1296 | + )) |
| 1297 | + |
| 1298 | + // The endpoint-level 'json' responseHandler overrides the global 'text', |
| 1299 | + // so the Accept header should be application/json |
| 1300 | + expect(request.headers['accept']).toBe('application/json') |
| 1301 | + }) |
| 1302 | + |
| 1303 | + test('does not override explicit Accept header from endpoint', async () => { |
| 1304 | + let request: any |
| 1305 | + ;({ data: request } = await baseQuery( |
| 1306 | + { |
| 1307 | + url: '/echo', |
| 1308 | + responseHandler: 'json', |
| 1309 | + headers: { Accept: 'application/xml' }, |
| 1310 | + }, |
| 1311 | + commonBaseQueryApi, |
| 1312 | + {}, |
| 1313 | + )) |
| 1314 | + |
| 1315 | + expect(request.headers['accept']).toBe('application/xml') |
| 1316 | + }) |
| 1317 | + |
| 1318 | + test('does not override Accept header set in prepareHeaders', async () => { |
| 1319 | + const customBaseQuery = fetchBaseQuery({ |
| 1320 | + baseUrl, |
| 1321 | + fetchFn: fetchFn as any, |
| 1322 | + prepareHeaders: (headers) => { |
| 1323 | + headers.set('Accept', 'application/vnd.api+json') |
| 1324 | + return headers |
| 1325 | + }, |
| 1326 | + }) |
| 1327 | + |
| 1328 | + let request: any |
| 1329 | + ;({ data: request } = await customBaseQuery( |
| 1330 | + { url: '/echo', responseHandler: 'json' }, |
| 1331 | + commonBaseQueryApi, |
| 1332 | + {}, |
| 1333 | + )) |
| 1334 | + |
| 1335 | + expect(request.headers['accept']).toBe('application/vnd.api+json') |
| 1336 | + }) |
| 1337 | + |
| 1338 | + test('does not set Accept header for content-type responseHandler', async () => { |
| 1339 | + let request: any |
| 1340 | + ;({ data: request } = await baseQuery( |
| 1341 | + { url: '/echo', responseHandler: 'content-type' }, |
| 1342 | + commonBaseQueryApi, |
| 1343 | + {}, |
| 1344 | + )) |
| 1345 | + |
| 1346 | + // Should either not have accept header or have a permissive one |
| 1347 | + // content-type handler adapts to whatever server sends |
| 1348 | + const acceptHeader = request.headers['accept'] |
| 1349 | + if (acceptHeader) { |
| 1350 | + expect(acceptHeader).toMatch(/\*\/\*/) |
| 1351 | + } |
| 1352 | + }) |
| 1353 | + |
| 1354 | + test('respects global responseHandler for Accept header', async () => { |
| 1355 | + const textBaseQuery = fetchBaseQuery({ |
| 1356 | + baseUrl, |
| 1357 | + fetchFn: fetchFn as any, |
| 1358 | + responseHandler: 'text', |
| 1359 | + }) |
| 1360 | + |
| 1361 | + let request: any |
| 1362 | + // Override to json just for this test so we can inspect the echoed request object |
| 1363 | + ;({ data: request } = await textBaseQuery( |
| 1364 | + { url: '/echo', responseHandler: 'json' }, |
| 1365 | + commonBaseQueryApi, |
| 1366 | + {}, |
| 1367 | + )) |
| 1368 | + |
| 1369 | + // The endpoint-level 'json' responseHandler overrides the global 'text', |
| 1370 | + // so the Accept header should be application/json (proving endpoint-level takes precedence) |
| 1371 | + expect(request.headers['accept']).toBe('application/json') |
| 1372 | + }) |
| 1373 | +}) |
| 1374 | + |
1258 | 1375 | describe('still throws on completely unexpected errors', () => { |
1259 | 1376 | test('', async () => { |
1260 | 1377 | const error = new Error('some unexpected error') |
|
0 commit comments