diff --git a/src/common/components/Recaptcha/Recaptcha.test.tsx b/src/common/components/Recaptcha/Recaptcha.test.tsx index 614988c42..f77a2e3dc 100644 --- a/src/common/components/Recaptcha/Recaptcha.test.tsx +++ b/src/common/components/Recaptcha/Recaptcha.test.tsx @@ -45,7 +45,7 @@ describe('Recaptcha component', () => { expect(recaptchaEnabledButton.innerHTML).toEqual('Label') }) - xit('should disable the button until ready', async () => { + it('should disable the button until ready', async () => { global.window.grecaptcha = undefined const { getByRole } = render(buildRecaptcha()) @@ -56,7 +56,7 @@ describe('Recaptcha component', () => { await waitFor(() => expect((recaptchaEnabledButton as HTMLButtonElement).disabled).toEqual(false)) }) - xit('should successfully pass the recaptcha', async () => { + it('should successfully pass the recaptcha', async () => { //@ts-ignore global.fetch = jest.fn(() => { return Promise.resolve({ @@ -77,7 +77,7 @@ describe('Recaptcha component', () => { }) }) - xit('should successfully pass the recaptcha on branded checkout', async () => { + it('should successfully pass the recaptcha on branded checkout', async () => { //@ts-ignore global.fetch = jest.fn(() => { return Promise.resolve({ @@ -98,7 +98,7 @@ describe('Recaptcha component', () => { }) }) - xit('should log a warning due to low score', async () => { + it('should log a warning due to low score', async () => { //@ts-ignore global.fetch = jest.fn(() => { return Promise.resolve({ @@ -119,7 +119,7 @@ describe('Recaptcha component', () => { }) }) - xit('should fail the recaptcha call', async () => { + it('should fail the recaptcha call', async () => { //@ts-ignore global.fetch = jest.fn(() => { return Promise.resolve({ @@ -140,11 +140,11 @@ describe('Recaptcha component', () => { }) }) - xit('should call the fail function when not a valid action', async () => { + it('should call the fail function when not a valid action', async () => { //@ts-ignore global.fetch = jest.fn(() => { return Promise.resolve({ - json: () => Promise.resolve({ success: true, action: 'read' }) + json: () => Promise.resolve({ success: true, action: 'read', score: 0.9 }) }) }) @@ -161,7 +161,7 @@ describe('Recaptcha component', () => { }) }) - xit('should skip the recaptcha call', async () => { + it('should skip the recaptcha call', async () => { //@ts-ignore global.window.grecaptcha = { ready: mockRecaptchaReady } @@ -178,7 +178,7 @@ describe('Recaptcha component', () => { }) }) - xit('should not block the gift if something went wrong with recaptcha', async () => { + it('should not block the gift if something went wrong with recaptcha', async () => { //@ts-ignore global.fetch = jest.fn(() => { return Promise.reject('Failed') @@ -198,7 +198,7 @@ describe('Recaptcha component', () => { }) }) - xit('should not block the gift if something went wrong with recaptcha JSON', async () => { + it('should not block the gift if something went wrong with recaptcha JSON', async () => { //@ts-ignore global.fetch = jest.fn(() => { return Promise.resolve({ @@ -220,11 +220,11 @@ describe('Recaptcha component', () => { }) }) - xit('should not block gifts if something weird happens', async () => { + it('should not block gifts if data is empty', async () => { //@ts-ignore global.fetch = jest.fn(() => { return Promise.resolve({ - json: () => Promise.resolve() + json: () => Promise.resolve({}) }) }) @@ -238,7 +238,51 @@ describe('Recaptcha component', () => { await waitFor(() => { expect(onSuccess).toHaveBeenCalledTimes(1) expect(onFailure).not.toHaveBeenCalled() - expect($log.warn).toHaveBeenCalledWith('Data was missing!') + expect($log.warn).toHaveBeenCalledWith('Recaptcha returned an unusual response:', {}) + }) + }) + + it('should not block gifts if action is undefined', async () => { + //@ts-ignore + global.fetch = jest.fn(() => { + return Promise.resolve({ + json: () => Promise.resolve({ success: true, score: 0.9 }) + }) + }) + + onSuccess.mockImplementation(() => console.log('success after weird')) + + const { getByRole } = render( + buildRecaptcha() + ) + + await userEvent.click(getByRole('button')) + await waitFor(() => { + expect(onSuccess).toHaveBeenCalledTimes(1) + expect(onFailure).not.toHaveBeenCalled() + expect($log.warn).toHaveBeenCalledWith('Recaptcha returned an unusual response:', { success: true, score: 0.9 }) + }) + }) + + it('should not block gifts if score is undefined', async () => { + //@ts-ignore + global.fetch = jest.fn(() => { + return Promise.resolve({ + json: () => Promise.resolve({ success: true, action: 'submit_gift' }) + }) + }) + + onSuccess.mockImplementation(() => console.log('success after weird')) + + const { getByRole } = render( + buildRecaptcha() + ) + + await userEvent.click(getByRole('button')) + await waitFor(() => { + expect(onSuccess).toHaveBeenCalledTimes(1) + expect(onFailure).not.toHaveBeenCalled() + expect($log.warn).toHaveBeenCalledWith('Recaptcha returned an unusual response:', { success: true, action: 'submit_gift' }) }) }) diff --git a/src/common/components/Recaptcha/Recaptcha.tsx b/src/common/components/Recaptcha/Recaptcha.tsx index 22760f64a..ddf7bf21e 100644 --- a/src/common/components/Recaptcha/Recaptcha.tsx +++ b/src/common/components/Recaptcha/Recaptcha.tsx @@ -71,50 +71,50 @@ export const Recaptcha = ({ }, [grecaptcha, buttonId]) const handleReCaptchaVerify = useCallback(async () => { - // if (!ready) { - // $log.info('Execute recaptcha not yet available') - // return - // } - - // grecaptcha.ready(async () => { - // try { - // const token = await grecaptcha.execute(recaptchaKey, { action: action }) - // const serverResponse = await fetch(`${apiUrl}/recaptcha/verify`, { - // method: 'POST', - // body: JSON.stringify({ token: token }), - // headers: { 'Content-Type': 'application/json' } - // }) - // const data = await serverResponse.json() - - // if (data?.success === true && isValidAction(data?.action)) { - // if (data.score < 0.5) { - // $log.warn(`Captcha score was below the threshold: ${data.score}`) - // onFailure(componentInstance) - // return - // } - // onSuccess(componentInstance) - // return - // } - // if (data?.success === false && isValidAction(data?.action)) { - // $log.warn('Recaptcha call was unsuccessful, continuing anyway') - // onSuccess(componentInstance) - // return - // } - // if (!data) { - // $log.warn('Data was missing!') - // onSuccess(componentInstance) - // return - // } - // if (!isValidAction(data?.action)) { - // $log.warn(`Invalid action: ${data?.action}`) - // onFailure(componentInstance) - // } - // } catch (error) { - // $log.error(`Failed to verify recaptcha, continuing on: ${error}`) - // onSuccess(componentInstance) - // } - // }) - onSuccess(componentInstance) + if (!ready) { + $log.info('Execute recaptcha not yet available') + return + } + + grecaptcha.ready(async () => { + try { + const token = await grecaptcha.execute(recaptchaKey, { action: action }) + const serverResponse = await fetch(`${apiUrl}/recaptcha/verify`, { + method: 'POST', + body: JSON.stringify({ token: token }), + headers: { 'Content-Type': 'application/json' } + }) + const data = await serverResponse.json() + + if (!data || !data.score || !data.action) { + $log.warn('Recaptcha returned an unusual response:', data) + onSuccess(componentInstance) + return + } + + if (data?.success === true && isValidAction(data?.action)) { + if (data.score < 0.5) { + $log.warn(`Captcha score was below the threshold: ${data.score}`) + onFailure(componentInstance) + return + } + onSuccess(componentInstance) + return + } + if (data?.success === false && isValidAction(data?.action)) { + $log.warn('Recaptcha call was unsuccessful, continuing anyway') + onSuccess(componentInstance) + return + } + if (!isValidAction(data?.action)) { + $log.warn(`Invalid action: ${data?.action}`) + onFailure(componentInstance) + } + } catch (error) { + $log.error(`Failed to verify recaptcha, continuing on: ${error}`) + onSuccess(componentInstance) + } + }) }, [grecaptcha, buttonId, ready]) return (