diff --git a/packages/altair-core/src/request/__snapshots__/response-builder.spec.ts.snap b/packages/altair-core/src/request/__snapshots__/response-builder.spec.ts.snap index 42be56e4af..794775aa6c 100644 --- a/packages/altair-core/src/request/__snapshots__/response-builder.spec.ts.snap +++ b/packages/altair-core/src/request/__snapshots__/response-builder.spec.ts.snap @@ -169,6 +169,17 @@ exports[`response-builder concatenate strategy should concatenate the responses ] `; +exports[`response-builder concatenate strategy should concatenate the responses and format the data if concatenated data is valid JSON 1`] = ` +[ + { + "content": "{ + "hello": "world" +}", + "timestamp": 1718252802585, + }, +] +`; + exports[`response-builder patch strategy should gather all errors from all responses 1`] = ` [ { diff --git a/packages/altair-core/src/request/handlers/http.spec.ts b/packages/altair-core/src/request/handlers/http.spec.ts index 3d9fe5c963..17eb59762e 100644 --- a/packages/altair-core/src/request/handlers/http.spec.ts +++ b/packages/altair-core/src/request/handlers/http.spec.ts @@ -341,6 +341,57 @@ describe('HTTP handler', () => { ]); }); + + it('should properly handle normal unsuccessful HTTP GET requests', async () => { + const mockHandler = new MswMockRequestHandler( + 'http://localhost:3000/graphql', + async () => { + return new Response('my data is not found', { + status: 404, + }); + } + ); + server.use(mockHandler); + + const request: GraphQLRequestOptions = { + url: 'http://localhost:3000/graphql', + method: 'GET', + additionalParams: { + testData: [ + { + hello: 'world', + }, + ], + }, + headers: [], + query: 'query { hello }', + variables: {}, + selectedOperation: 'hello', + }; + + const httpHandler: GraphQLRequestHandler = new HttpRequestHandler(); + const res = await testObserver(httpHandler.handle(request)); + + const receivedRequest = mockHandler.receivedRequest(); + expect(receivedRequest?.url).toEqual( + 'http://localhost:3000/graphql?query=query+%7B+hello+%7D&variables=%7B%7D&operationName=hello' + ); + expect(receivedRequest?.body).toBeNull(); + + expect(res).toEqual([ + expect.objectContaining({ + ok: false, + data: 'my data is not found', + headers: expect.any(Object), + status: 404, + url: 'http://localhost:3000/graphql?query=query+%7B+hello+%7D&variables=%7B%7D&operationName=hello', + requestStartTimestamp: expect.any(Number), + requestEndTimestamp: expect.any(Number), + resopnseTimeMs: expect.any(Number), + }), + ]); + }); + it('should properly handle failed HTTP requests', async () => { const mockHandler = new MswMockRequestHandler( 'http://localhost:3000/error', diff --git a/packages/altair-core/src/request/handlers/http.ts b/packages/altair-core/src/request/handlers/http.ts index 6f3e327346..e2c64e52a7 100644 --- a/packages/altair-core/src/request/handlers/http.ts +++ b/packages/altair-core/src/request/handlers/http.ts @@ -49,9 +49,10 @@ export class HttpRequestHandler implements GraphQLRequestHandler { if (!merosResponse.ok || !merosResponse.body) { // don't handle streaming + const buffer = await merosResponse.arrayBuffer() return this.emitChunk( merosResponse, - new Uint8Array(), + new Uint8Array(buffer), true, observer, requestStartTime, diff --git a/packages/altair-core/src/request/response-builder.spec.ts b/packages/altair-core/src/request/response-builder.spec.ts index 6f123a3e1b..7300bd5c9d 100644 --- a/packages/altair-core/src/request/response-builder.spec.ts +++ b/packages/altair-core/src/request/response-builder.spec.ts @@ -161,6 +161,20 @@ describe('response-builder', () => { expect(res).toMatchSnapshot(); }); + it('should concatenate the responses and format the data if concatenated data is valid JSON', () => { + const res = buildResponse([ + { + content: '{"hello":', + timestamp: 1718252802585 + }, + { + content: '"world"}', + timestamp: 1718252802585, + } + ]) + expect(res).toMatchSnapshot(); + }); + it('should return timestamp as 0 if no responses are provided', () => { const res = buildResponse([], MultiResponseStrategy.CONCATENATE); expect(res).toEqual([ diff --git a/packages/altair-core/src/request/response-builder.ts b/packages/altair-core/src/request/response-builder.ts index 65cd3d9175..92c5d19561 100644 --- a/packages/altair-core/src/request/response-builder.ts +++ b/packages/altair-core/src/request/response-builder.ts @@ -92,9 +92,11 @@ export const buildResponse = ( }; const buildResponse__concatenate = (responses: QueryResponse[]): QueryResponse[] => { + const content = responses.map((r) => r.content).join(''); + const parsedContent = parseJson(content, {defaultValue: null}); return [ { - content: responses.map((r) => r.content).join(''), + content: parsedContent ? JSON.stringify(parsedContent, null, 2) : content, timestamp: responses.at(-1)?.timestamp ?? 0, }, ];