From 9a634487576d405e9987eda3f82019797df391bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?France=20B=C3=A9rut?= Date: Thu, 31 Jul 2025 10:49:40 +0200 Subject: [PATCH] fix(fetch): returns error in case api response contains 'errors' key --- src/hooks/useFetchEligibility.test.ts | 33 ++++++++++++++++++++++++++- src/hooks/useFetchEligibility.ts | 4 +++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/hooks/useFetchEligibility.test.ts b/src/hooks/useFetchEligibility.test.ts index b62b874f..f02c38b2 100644 --- a/src/hooks/useFetchEligibility.test.ts +++ b/src/hooks/useFetchEligibility.test.ts @@ -81,7 +81,7 @@ describe('useFetchEligibility', () => { expect(fetchFromApi).not.toHaveBeenCalled() }) - it('should returns a FAILED status if the API response is from ErrorType', async () => { + it('should returns a FAILED status if the API response contains `error_code`', async () => { const mockedSessionStorage = { getCache: jest.fn(), setCache: jest.fn(), @@ -104,6 +104,37 @@ describe('useFetchEligibility', () => { ), ) + // Status should be failed + await waitFor(() => { + expect(result.current[1]).toBe(statusResponse.FAILED) + }) + // The cache should not be set + expect(mockedSessionStorage?.setCache).not.toHaveBeenCalled() + // The hook response should be empty + expect(result.current[0]).toEqual([]) + }) + it('should returns a FAILED status if the API response contains `errors`', async () => { + const mockedSessionStorage = { + getCache: jest.fn(), + setCache: jest.fn(), + createKey: jest.fn().mockReturnValue('mocked_key'), + clearCache: jest.fn(), + } + ;(useSessionStorage as jest.Mock).mockReturnValue(mockedSessionStorage) + ;(fetchFromApi as jest.Mock).mockImplementation(async () => ({ + errors: 'some error', + })) + + const { result } = renderHook(() => + useFetchEligibility( + 45000, + { domain: ApiMode.TEST, merchantId: 'test_id' }, + undefined, + 'FR', + 'FR', + ), + ) + // Status should be failed await waitFor(() => { expect(result.current[1]).toBe(statusResponse.FAILED) diff --git a/src/hooks/useFetchEligibility.ts b/src/hooks/useFetchEligibility.ts index 0bacbe90..481811f2 100644 --- a/src/hooks/useFetchEligibility.ts +++ b/src/hooks/useFetchEligibility.ts @@ -76,7 +76,9 @@ const useFetchEligibility = ( ) .then((res) => { // If the response contains an error_code, we set the status to failed - for example if code is 403 unauthorized - if ('error_code' in res) { + // When purchase amount & plans are not compatible, the API returns an error {"running": {"message": "'purchase_amount'"}} which does not contain the key `error_code` + // And the widget keeps loading if we don't handle it, so we need to cover this case and returns a FAILED status + if ('error_code' in res || 'errors' in res) { setStatus(statusResponse.FAILED) } else { setEligibility(res as EligibilityPlan[])