Skip to content

Commit

Permalink
fix(execute): Handle async opts (#238)
Browse files Browse the repository at this point in the history
Co-authored-by: Zoryana Vakh <[email protected]>
  • Loading branch information
gabrielferreira-imi and zoryana94 authored Aug 14, 2024
1 parent 491bb96 commit 1066685
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 12 deletions.
6 changes: 5 additions & 1 deletion demo/app/examples/AsyncExample.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef } from 'react';
import React, { useRef, useEffect } from 'react';

import HCaptcha from '../../../src/index.js';

Expand All @@ -17,6 +17,10 @@ export function AsyncExample() {
}
};

useEffect(() => {
executeCaptcha();
}, []);

const getResponse = () => {
try {
const res = captchaRef.current.getResponse();
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hcaptcha/react-hcaptcha",
"version": "1.10.3",
"version": "1.11.0",
"types": "types/index.d.ts",
"main": "dist/index.js",
"module": "dist/esm/index.js",
Expand Down
41 changes: 31 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class HCaptcha extends React.Component {
this.resetCaptcha = this.resetCaptcha.bind(this);
this.removeCaptcha = this.removeCaptcha.bind(this);
this.isReady = this.isReady.bind(this);
this._onReady = null;

// Event Handlers
this.loadCaptcha = this.loadCaptcha.bind(this);
Expand Down Expand Up @@ -191,6 +192,7 @@ class HCaptcha extends React.Component {

this.setState({ isRemoved: false, captchaId }, () => {
onReady && onReady();
this._onReady && this._onReady(captchaId);
});
}

Expand Down Expand Up @@ -230,7 +232,7 @@ class HCaptcha extends React.Component {
});
}

handleOnLoad () {
handleOnLoad () {
this.setState({ isApiReady: true }, () => {
try {
const element = getMountElement(this.props.scriptLocation);
Expand Down Expand Up @@ -327,22 +329,41 @@ class HCaptcha extends React.Component {
}

execute (opts = null) {

opts = typeof opts === 'object' ? opts : null;

try {
const { captchaId } = this.state;
const hcaptcha = this._hcaptcha;



if (!this.isReady()) {
return;
}

if (opts && typeof opts !== "object") {
opts = null;
const onReady = new Promise((resolve, reject) => {

this._onReady = (id) => {
try {
const hcaptcha = this._hcaptcha;

if (opts && opts.async) {
hcaptcha.execute(id, opts).then(resolve).catch(reject);
} else {
resolve(hcaptcha.execute(id, opts));
}
} catch (e) {
reject(e);
}
};
});

return opts?.async ? onReady : null;
}

return hcaptcha.execute(captchaId, opts);
} catch (error) {
this.sentryHub.captureException(error);
this.sentryHub.captureException(error);
if (opts && opts.async) {
return Promise.reject(error);
}
return null;
}
}

Expand Down
32 changes: 32 additions & 0 deletions tests/hcaptcha.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,38 @@ describe("hCaptcha", () => {
expect(window.hcaptcha.execute).toBeCalledWith(MOCK_WIDGET_ID, null);
});

it("stores and calls execute after hCaptcha onload is executed", async () => {
jest.spyOn(instance, 'isReady').mockReturnValueOnce(false);
instance.execute();
expect(window.hcaptcha.execute.mock.calls.length).toBe(0);
await instance._onReady(MOCK_WIDGET_ID);
expect(window.hcaptcha.execute.mock.calls.length).toBe(1);
expect(window.hcaptcha.execute).toBeCalledWith(MOCK_WIDGET_ID, null);
});

it("stores the execute command and calls it after hCaptcha onload is executed", async () => {
jest.spyOn(instance, 'isReady').mockReturnValueOnce(false);

const onLoad = jest.fn(() => {
expect(instance.state.captchaId).toBe(MOCK_WIDGET_ID);
});

instance = ReactTestUtils.renderIntoDocument(
<HCaptcha
sitekey={TEST_PROPS.sitekey}
onLoad={onLoad}
sentry={false}
/>,
);
expect(window.hcaptcha.execute.mock.calls.length).toBe(0);

instance.execute();
instance.handleOnLoad();

expect(window.hcaptcha.execute.mock.calls.length).toBe(1);
expect(window.hcaptcha.execute).toBeCalledWith(MOCK_WIDGET_ID, null);
});

it("can execute synchronously with async: false", () => {
expect(window.hcaptcha.execute.mock.calls.length).toBe(0);
instance.execute({ async: false });
Expand Down

0 comments on commit 1066685

Please sign in to comment.