Skip to content

Commit

Permalink
Merge pull request dozoisch#34 from ptondereau/invisible-feature
Browse files Browse the repository at this point in the history
Add invisible props and execute method
  • Loading branch information
dozoisch authored Mar 16, 2017
2 parents cbfe092 + b2e5296 commit 170a642
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 45 deletions.
18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

[*.js]
charset = utf-8
indent_style = space
indent_size = 2

[{package.json,.travis.yml}]
indent_style = space
indent_size = 2
4 changes: 3 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"comma-dangle": [2, "always-multiline"],
"comma-spacing": 1,
"key-spacing": 0,
"indent": ["error", 2],
"no-mixed-spaces-and-tabs": 2,
"no-multiple-empty-lines": [1, { "max": 1}],
"no-underscore-dangle": 0,
Expand All @@ -31,7 +32,8 @@
"react/prop-types": 1,
"react/react-in-jsx-scope": 1,
"react/self-closing-comp": 1,
"react/wrap-multilines": 1,
"react/jsx-wrap-multilines": 1,
"semi": ["error", "always"],
"strict": [1, "never"]
}
}
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ module.exports = function (config) {

autoWatch: true,

browsers: [ isCI ? "PhantomJS" : "Chrome" ],
browsers: [isCI ? "PhantomJS" : "Chrome"],

captureTimeout: 60000,
browserNoActivityTimeout: 30000,
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"scripts": {
"build": "rm -rf lib && babel src --out-dir lib",
"lint": "eslint ./",
"lint:fix": "eslint ./ --fix",
"test": "karma start --single-run",
"test-watch": "karma start",
"patch": "release patch --run",
Expand Down Expand Up @@ -49,9 +50,9 @@
"babel-runtime": "^6.0.0",
"chai": "^3.5.0",
"es5-shim": "^4.5.0",
"eslint": "~1.6.0",
"eslint-config-defaults": "~7.0.1",
"eslint-plugin-react": "~3.5.1",
"eslint": "^3.17.1",
"eslint-config-defaults": "^9.0.0",
"eslint-plugin-react": "^6.10.0",
"karma": "~0.13.9",
"karma-chai": "~0.1.0",
"karma-chrome-launcher": "~0.2.0",
Expand Down
8 changes: 4 additions & 4 deletions src/recaptcha-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import makeAsyncScriptLoader from "react-async-script";

const callbackName = "onloadcallback";
const lang = typeof window !== "undefined" && (window.recaptchaOptions && window.recaptchaOptions.lang) ?
"&hl=" + window.recaptchaOptions.lang :
`&hl=${window.recaptchaOptions.lang}` :
"";
const URL = `https://www.google.com/recaptcha/api.js?onload=${callbackName}&render=explicit${lang}`;
const globalName = "grecaptcha";

export default makeAsyncScriptLoader(ReCAPTCHA, URL, {
callbackName: callbackName,
globalName: globalName,
exposeFuncs: ["getValue", "reset"],
callbackName,
globalName,
exposeFuncs: ["getValue", "reset", "execute"],
});
31 changes: 20 additions & 11 deletions src/recaptcha.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ const ReCAPTCHA = React.createClass({
type: PropTypes.oneOf(["image", "audio"]),
tabindex: PropTypes.number,
onExpired: PropTypes.func,
size: PropTypes.oneOf(["compact", "normal"]),
size: PropTypes.oneOf(["compact", "normal", "invisible"]),
stoken: PropTypes.string,
},

getInitialState() {
getInitialState () {
return {};
},

getDefaultProps() {
getDefaultProps () {
return {
theme: "light",
type: "image",
Expand All @@ -27,30 +27,39 @@ const ReCAPTCHA = React.createClass({
};
},

getValue() {
getValue () {
if (this.props.grecaptcha && this.state.widgetId !== undefined) {
return this.props.grecaptcha.getResponse(this.state.widgetId);
}
return null;
},

reset() {
execute () {
const { grecaptcha } = this.props;
const { widgetId } = this.state;

if (grecaptcha && widgetId !== undefined) {
return grecaptcha.execute(widgetId);
}
},

reset () {
if (this.props.grecaptcha && this.state.widgetId !== undefined) {
this.props.grecaptcha.reset(this.state.widgetId);
}
},

handleExpired() {
handleExpired () {
if (this.props.onExpired) {
this.props.onExpired();
} else if (this.props.onChange) {
this.props.onChange(null);
}
},

explicitRender(cb) {
explicitRender (cb) {
if (this.props.grecaptcha && this.state.widgetId === undefined) {
let id = this.props.grecaptcha.render(this.refs.captcha, {
const id = this.props.grecaptcha.render(this.refs.captcha, {
sitekey: this.props.sitekey,
callback: this.props.onChange,
theme: this.props.theme,
Expand All @@ -66,15 +75,15 @@ const ReCAPTCHA = React.createClass({
}
},

componentDidMount() {
componentDidMount () {
this.explicitRender();
},

componentDidUpdate() {
componentDidUpdate () {
this.explicitRender();
},

render() {
render () {
// consume properties owned by the reCATPCHA, pass the rest to the div so the user can style it.
/* eslint-disable no-unused-vars */
const { sitekey, onChange, theme, type, tabindex, onExpired, size, stoken, grecaptcha, ...childProps } = this.props;
Expand Down
54 changes: 35 additions & 19 deletions test/recaptcha-spec.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,72 @@
import React from "react";
import ReactDOM from "react-dom";
import ReactTestUtils from "react-addons-test-utils";
import ReCAPTCHA from "../src/recaptcha";
import ReCAPTCHA from "../src/recaptcha"; // eslint-disable-line no-unused-vars

describe("ReCAPTCHA", () => {
it("Rendered Component should be a div", () => {
let instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx" />
);
const instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx" />,
);
assert.equal(ReactDOM.findDOMNode(instance).nodeName, "DIV");
});
it("Rendered Component should contained passed props", () => {
let props = {
const props = {
className: "TheClassName",
id: "superdefinedId",
};
let instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx" {...props} />
);
const instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx" {...props} />,
);
assert.equal(ReactDOM.findDOMNode(instance).id, props.id);
assert.match(ReactDOM.findDOMNode(instance).className, new RegExp(props.className));
});

it("should call grecaptcha.render, when it is already loaded", (done) => {
let grecaptchaMock = {
render(node, options) {
const grecaptchaMock = {
render (node, options) {
assert.isNotNull(node);
assert.equal(options.sitekey, "xxx");
done();
},
};
let instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx" grecaptcha={grecaptchaMock} />
);
const instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx" grecaptcha={grecaptchaMock} />,
);
assert.ok(instance);
});
it("reset, should call grecaptcha.reset with the widget id", (done) => {
let grecaptchaMock = {
render() {
const grecaptchaMock = {
render () {
return "someWidgetId";
},

reset(widgetId) {
reset (widgetId) {
assert.isNotNull(widgetId);
done();
},
};
let instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx" grecaptcha={grecaptchaMock} />
);
const instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx" grecaptcha={grecaptchaMock} />,
);
instance.reset();
});
it("execute, should call grecaptcha.execute with the widget id", (done) => {
const grecaptchaMock = {
render () {
return "someWidgetId";
},

execute (widgetId) {
assert.isNotNull(widgetId);
done();
},
};
const instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx" size="invisible" grecaptcha={grecaptchaMock} />,
);
instance.execute();
});
describe("Expired", () => {
it("should call onChange with null when response is expired");
it("should call onExpired when response is expired");
Expand Down
12 changes: 6 additions & 6 deletions test/recaptcha-wrapper-spec.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import React from "react";
import ReactTestUtils from "react-addons-test-utils";
import ReCAPTCHA from "../src/recaptcha-wrapper";
import ReCAPTCHA from "../src/recaptcha-wrapper"; // eslint-disable-line no-unused-vars

const VALUE = "some value";
const WIDGET_ID = "someWidgetId";

let grecaptchaMock = {
render(node, options) {
const grecaptchaMock = {
render (node, options) {
assert.ok(node, options);
return WIDGET_ID;
},

getResponse(widgetId) {
getResponse (widgetId) {
assert.equal(widgetId, WIDGET_ID);
return VALUE;
},
Expand All @@ -22,8 +22,8 @@ describe("ReCAPTCHAWrapper", () => {
window.grecaptcha = grecaptchaMock;
});
it("should proxy functions", () => {
let instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx"/>
const instance = ReactTestUtils.renderIntoDocument(
<ReCAPTCHA sitekey="xxx" />,
);
assert.ok(instance);
assert.equal(instance.getValue(), VALUE);
Expand Down

0 comments on commit 170a642

Please sign in to comment.