diff --git a/package.json b/package.json index f4b5a39..1f3db36 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "bundlesize": [ { "path": "./dist/react-gpt.min.js", - "maxSize": "8.5 kB" + "maxSize": "8.53 kB" } ] } diff --git a/src/Bling.js b/src/Bling.js index 96a39d2..9d3a99d 100644 --- a/src/Bling.js +++ b/src/Bling.js @@ -196,7 +196,17 @@ class Bling extends React.Component { * * @property style */ - style: PropTypes.object + style: PropTypes.object, + /** + * An optional property to control non-personalized Ads. + * https://support.google.com/admanager/answer/7678538 + * + * Set to `true` to mark the ad request as NPA, and to `false` for ad requests that are eligible for personalized ads + * It is `false` by default, according to Google's definition. + * + * @property npa + */ + npa: PropTypes.bool }; /** @@ -222,7 +232,13 @@ class Bling extends React.Component { * @property reRenderProps * @static */ - static reRenderProps = ["adUnitPath", "slotSize", "outOfPage", "content"]; + static reRenderProps = [ + "adUnitPath", + "slotSize", + "outOfPage", + "content", + "npa" + ]; /** * An instance of ad manager. * @@ -456,10 +472,9 @@ class Bling extends React.Component { this.props, nextProps ); - const shouldRender = !propsEqual( - reRenderProps.props, - reRenderProps.nextProps - ); + const shouldRender = + !this._adSlot || + !propsEqual(reRenderProps.props, reRenderProps.nextProps); const shouldRefresh = !shouldRender && !propsEqual(refreshableProps.props, refreshableProps.nextProps); @@ -656,10 +671,12 @@ class Bling extends React.Component { } defineSlot() { - const {adUnitPath, outOfPage} = this.props; + const { adUnitPath, outOfPage, npa } = this.props; const divId = this._divId; const slotSize = this.getSlotSize(); + this.handleSetNpaFlag(npa); + if (!this._adSlot) { // May need additional OOP logic later if (outOfPage) { @@ -830,6 +847,24 @@ class Bling extends React.Component { return
; } + + /** + * Call pubads and set the non-personalized Ads flag, if it is not undefined. + * + * @param {boolean} npa + */ + handleSetNpaFlag(npa) { + if (npa === undefined) { + return; + } + + Bling._adManager.pubadsProxy({ + method: "setRequestNonPersonalizedAds", + args: [npa ? 1 : 0], + resolve: null, + reject: null + }); + } } // proxy pubads API through Bling diff --git a/test/Bling.spec.js b/test/Bling.spec.js index 62378b4..4657e07 100644 --- a/test/Bling.spec.js +++ b/test/Bling.spec.js @@ -163,6 +163,45 @@ describe("Bling", () => { ); }); + it("call pubads API to set non-personalized Ads when npa prop is set", done => { + const spy = sinon.stub(Bling._adManager, "pubadsProxy"); + const expectedParamTrue = { + method: "setRequestNonPersonalizedAds", + args: [1], + resolve: null, + reject: null + }; + const expectedParamFalse = { + ...expectedParamTrue, + args: [0] + }; + + Bling.once(Events.RENDER, () => { + expect(spy.calledWith(expectedParamTrue)).to.be.true; + expect(spy.calledWith(expectedParamFalse)).to.be.true; + spy.restore(); + done(); + }); + + // Render once to test with non-personalized ads + ReactTestUtils.renderIntoDocument( + + ); + + // Render a second time to test re-enable personalized ads + ReactTestUtils.renderIntoDocument( + + ); + }); + it("fires once event", done => { const events = Object.keys(Events).map(key => Events[key]);