diff --git a/docs/sdk/README.md b/docs/sdk/README.md index 116cc6338..c1ab19fa0 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -23,7 +23,7 @@ If we take a step back and look at the general requirement, at the end we simply In this example (integration test) we are going to make some requests to the `/channels` API endpoint. For that we need to be able to make actual requests (`http` middleware) as well as to authenticate the requests using the API Client Credentials Flow (`auth` middleware). -The `queue` middleware is not really necessary in this simple example but it is usually useful to limit a bit the number of concurrent requests. +The `queue` middleware is not really necessary in this simple example but it is usually useful to limit a bit the number of concurrent requests and should be place before the `http` middleware. The `api-request-builder` package comes in handy to easily construct the request _URI_ but it is not really necessary as the _URI_ could be also typed manually. @@ -54,7 +54,7 @@ const queueMiddleware = createQueueMiddleware({ concurrency: 5, }) const client = createClient({ - middlewares: [authMiddleware, httpMiddleware, queueMiddleware], + middlewares: [authMiddleware, queueMiddleware, httpMiddleware], }) describe('Channels', () => { diff --git a/integration-tests/cli/helpers/personal-data-erasure.data.js b/integration-tests/cli/helpers/personal-data-erasure.data.js index 0000c22e0..9ad2adf23 100644 --- a/integration-tests/cli/helpers/personal-data-erasure.data.js +++ b/integration-tests/cli/helpers/personal-data-erasure.data.js @@ -63,7 +63,7 @@ export const customLineItem = [ slug: 'mySlug', taxCategory: { typeId: 'tax-category', - id: 'fd890829-7554-4c22-a806-d6c6dcdbb0c5', + id: 'd205cc42-e399-424a-b6fc-0ef44772d6bc', }, }, ], diff --git a/integration-tests/cli/personal-data-erasure.it.js b/integration-tests/cli/personal-data-erasure.it.js index a7166a004..27cee3580 100644 --- a/integration-tests/cli/personal-data-erasure.it.js +++ b/integration-tests/cli/personal-data-erasure.it.js @@ -105,7 +105,19 @@ describe('personal data erasure', () => { it('should get data on the CTP', async () => { const data = await personalDataErasure.getCustomerData(customerId) - expect(data).toHaveLength(10) + expect(data).toHaveLength(11) + expect(data).toContainEqual(expect.objectContaining({type: 'CartCreated'})) + expect(data).toContainEqual(expect.objectContaining({type: 'PaymentCreated'})) + expect(data).toContainEqual(expect.objectContaining({type: 'CustomerCreated'})) + expect(data).toContainEqual(expect.objectContaining({type: 'ReviewCreated'})) + expect(data).toContainEqual(expect.objectContaining({type: 'OrderCreated'})) + expect(data).toContainEqual(expect.objectContaining({type: 'CartCreated'})) + expect(data).toContainEqual(expect.objectContaining({type: 'Order'})) + expect(data).toContainEqual(expect.objectContaining({type: 'Cart'})) + expect(data).toContainEqual(expect.objectContaining({email: 'foo@bar.de'})) + expect(data).toContainEqual(expect.objectContaining({amountPlanned: { type: 'centPrecision', currencyCode: 'EUR', centAmount: 100, fractionDigits: 2}})) + expect(data).toContainEqual(expect.objectContaining({name: {de: 'deutscherListenName', en: 'englishListName'}})) + expect(data).toContainEqual(expect.objectContaining({text: 'Review text'})) }) }) diff --git a/packages/sdk-middleware-http/src/http.js b/packages/sdk-middleware-http/src/http.js index 73ee39907..905f81527 100644 --- a/packages/sdk-middleware-http/src/http.js +++ b/packages/sdk-middleware-http/src/http.js @@ -68,13 +68,18 @@ export default function createHttpMiddleware({ } = {}, fetch: fetcher, abortController: _abortController, - getAbortController + getAbortController, }: HttpMiddlewareOptions): Middleware { if (!fetcher && typeof fetch === 'undefined') throw new Error( '`fetch` is not available. Please pass in `fetch` as an option or have it globally available.' ) - if (timeout && !getAbortController && !_abortController && typeof AbortController === 'undefined') + if ( + timeout && + !getAbortController && + !_abortController && + typeof AbortController === 'undefined' + ) throw new Error( '`AbortController` is not available. Please pass in `getAbortController` as an option or have AbortController globally available when using timeout.' ) @@ -95,7 +100,10 @@ export default function createHttpMiddleware({ let abortController: any if (timeout || getAbortController || _abortController) // eslint-disable-next-line - abortController = (getAbortController ? getAbortController(): null) || _abortController || new AbortController() + abortController = + (getAbortController ? getAbortController() : null) || + _abortController || + new AbortController() const url = host.replace(/\/$/, '') + request.uri const body = @@ -148,9 +156,31 @@ export default function createHttpMiddleware({ } res.text().then((result: Object) => { + // Try to parse the response as JSON + let parsed + try { + parsed = result.length > 0 ? JSON.parse(result) : {} + } catch (err) { + if (enableRetry && retryCount < maxRetries) { + setTimeout( + executeFetch, + calcDelayDuration( + retryCount, + retryDelay, + maxRetries, + backoff, + maxDelay + ) + ) + retryCount += 1 + return + } + parsed = result + } + const parsedResponse: Object = { ...response, - body: result.length > 0 ? JSON.parse(result) : {}, + body: parsed, statusCode: res.status, } diff --git a/packages/sdk-middleware-http/test/http.spec.js b/packages/sdk-middleware-http/test/http.spec.js index a366d2af9..2505b1dd8 100644 --- a/packages/sdk-middleware-http/test/http.spec.js +++ b/packages/sdk-middleware-http/test/http.spec.js @@ -70,6 +70,72 @@ describe('Http', () => { httpMiddleware(next)(request, response) })) + test("execute a get request which doesn't return a json response", () => + new Promise((resolve, reject) => { + const request = createTestRequest({ + uri: '/foo/bar', + }) + const response = { resolve, reject } + const next = (req, res) => { + expect(res).toEqual({ + ...response, + body: 'not json response', + statusCode: 200, + }) + resolve() + } + // Use default options + const httpMiddleware = createHttpMiddleware({ + host: testHost, + fetch, + }) + nock(testHost) + .defaultReplyHeaders({ + 'Content-Type': 'application/json', + }) + .get('/foo/bar') + .reply(200, 'not json response') + + httpMiddleware(next)(request, response) + })) + + test("execute a get request which doesn't return a json response with retry", () => + new Promise((resolve, reject) => { + const request = createTestRequest({ + uri: '/foo/bar', + }) + const response = { resolve, reject } + const next = (req, res) => { + expect(res).toEqual({ + ...response, + body: { foo: 'bar' }, + statusCode: 200, + }) + resolve() + } + // Use default options + const httpMiddleware = createHttpMiddleware({ + host: testHost, + fetch, + enableRetry: true, + }) + nock(testHost) + .defaultReplyHeaders({ + 'Content-Type': 'application/json', + }) + .get('/foo/bar') + .reply(200, 'not json response') + + nock(testHost) + .defaultReplyHeaders({ + 'Content-Type': 'application/json', + }) + .get('/foo/bar') + .reply(200, { foo: 'bar' }) + + httpMiddleware(next)(request, response) + })) + test('execute a get request with timeout (success)', () => new Promise((resolve, reject) => { const request = createTestRequest({