Skip to content

Commit

Permalink
Troubleshoot for AMP pages (ampproject#11920)
Browse files Browse the repository at this point in the history
* Init.

* stashing changes.

* Cases slotid correctly.

* Added test and finalized message attributes.

* Removing test code.

* Clean up + negative test.

* Added comments.

* Fixed comments and test.

* Fixing presubmit errors.

* Make more obvious what negative test is testing.

* Gathering all Troubleshoot data into single type/object.

* Fixing docstring.

* Moved troubleshootData initializations earlier into constructor.

* Made postTroubleshootMessage public and visible for testing.

* Moving things back to buildCallback.
  • Loading branch information
glevitzky authored and gzgogo committed Jan 26, 2018
1 parent acdad5c commit 7867de9
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 2 deletions.
Expand Up @@ -141,6 +141,15 @@ export const SAFEFRAME_ORIGIN = 'https://tpc.googlesyndication.com';
/** @private {?Promise} */
let sraRequests = null;

/** @typedef {{
adUrl: !Promise<string>,
lineItemId: string,
creativeId: string,
slotId: string,
slotIndex: string,
}} */
let TroubleshootData;

/**
* Array of functions used to combine block level request parameters for SRA
* request.
Expand Down Expand Up @@ -353,6 +362,9 @@ export class AmpAdNetworkDoubleclickImpl extends AmpA4A {

/** @private {boolean} */
this.preloadSafeframe_ = true;

/** @private {!TroubleshootData} */
this.troubleshootData_ = /** @type {!TroubleshootData} */ ({});
}

/** @override */
Expand Down Expand Up @@ -394,6 +406,9 @@ export class AmpAdNetworkDoubleclickImpl extends AmpA4A {
.then(() => getIdentityToken(this.win, this.getAmpDoc())) :
Promise.resolve(
/**@type {!../../../ads/google/a4a/utils.IdentityToken}*/({}));
this.troubleshootData_.slotId = this.element.getAttribute('data-slot');
this.troubleshootData_.slotIndex =
this.element.getAttribute('data-amp-slot-index');
if (this.win['dbclk_a4a_viz_change']) {
// Only create one per page but ensure all slots get experiment
// selection.
Expand Down Expand Up @@ -598,15 +613,17 @@ export class AmpAdNetworkDoubleclickImpl extends AmpA4A {
// On error/timeout, proceed.
return /**@type {!../../../ads/google/a4a/utils.IdentityToken}*/({});
});
return Promise.all([opt_rtcResponsesPromise, identityPromise]).then(
results => {
const urlPromise = Promise.all([opt_rtcResponsesPromise, identityPromise])
.then(results => {
const rtcParams = this.mergeRtcResponses_(results[0]);
this.identityToken = results[1];
return googleAdUrl(
this, DOUBLECLICK_BASE_URL, startTime, Object.assign(
this.getBlockParameters_(), rtcParams,
this.buildIdentityParams_(), PAGE_LEVEL_PARAMS_));
});
this.troubleshootData_.adUrl = urlPromise;
return urlPromise;
}

/**
Expand Down Expand Up @@ -695,6 +712,10 @@ export class AmpAdNetworkDoubleclickImpl extends AmpA4A {
setGoogleLifecycleVarsFromHeaders(responseHeaders, this.lifecycleReporter_);
this.ampAnalyticsConfig_ = extractAmpAnalyticsConfig(this, responseHeaders);
this.qqid_ = responseHeaders.get(QQID_HEADER);
this.troubleshootData_.creativeId =
responseHeaders.get('google-creative-id');
this.troubleshootData_.lineItemId =
responseHeaders.get('google-lineitem-id');
if (this.ampAnalyticsConfig_) {
// Load amp-analytics extensions
this.extensions_./*OK*/installExtensionForDoc(
Expand Down Expand Up @@ -908,6 +929,8 @@ export class AmpAdNetworkDoubleclickImpl extends AmpA4A {
}
return true;
});

this.postTroubleshootMessage();
}

/**
Expand Down Expand Up @@ -1209,6 +1232,45 @@ export class AmpAdNetworkDoubleclickImpl extends AmpA4A {
this.win.removeEventListener('message', fluidMessageListener_);
}
}

/**
* Emits a postMessage containing information about this slot to the DFP
* Troubleshoot UI. A promise is returned if a message is posted, otherwise
* null is returned. The promise is returned only for test convenience.
*
* @return {?Promise}
* @visibleForTesting
*/
postTroubleshootMessage() {
if (!this.win.opener || !/[?|&]dfpdeb/.test(this.win.location.search)) {
return null;
}
dev().assert(this.troubleshootData_.adUrl, 'ad URL does not exist yet');
return this.troubleshootData_.adUrl.then(adUrl => {
const payload = dict({
'gutData': JSON.stringify(dict({
'events': [{
'timestamp': Date.now(),
'slotid': this.troubleshootData_.slotId,
'messageId': 4,
}],
'slots': [{
'contentUrl': adUrl || '',
'id': this.troubleshootData_.slotId,
'leafAdUnitName': this.troubleshootData_.slotId,
'domId': 'gpt_unit_' + this.troubleshootData_.slotId + '_' +
this.troubleshootData_.slotIndex,
'lineItemId': this.troubleshootData_.lineItemId,
'creativeId': this.troubleshootData_.creativeId,
}],
})),
'userAgent': navigator.userAgent,
'referrer': this.win.location.href,
'messageType': 'LOAD',
});
this.win.opener./*OK*/postMessage(payload, '*');
});
}
}


Expand Down
Expand Up @@ -1064,6 +1064,80 @@ describes.realWin('amp-ad-network-doubleclick-impl', realWinConfig, env => {
['https://partner.googleadservices.com', SAFEFRAME_ORIGIN]);
});
});

describe('Troubleshoot for AMP pages', () => {
beforeEach(() => {
element = doc.createElement('amp-ad');
element.setAttribute('type', 'doubleclick');
doc.body.appendChild(element);
impl = new AmpAdNetworkDoubleclickImpl(element);
impl.troubleshootData_ = {
adUrl: Promise.resolve('http://www.getmesomeads.com'),
creativeId: '123',
lineItemId: '456',
slotId: 'slotId',
slotIndex: '0',
};
});

afterEach(() => {
doc.body.removeChild(element);
});

it('should emit post message', () => {
const slotId = 'slotId';
env.win = {
location: {
href: 'http://localhost:8000/foo?dfpdeb',
search: '?dfpdeb',
},
opener: {
postMessage: payload => {
expect(payload).to.be.ok;
expect(payload.userAgent).to.be.ok;
expect(payload.referrer).to.be.ok;
expect(payload.messageType).to.equal('LOAD');

const gutData = JSON.parse(payload.gutData);
expect(gutData).to.be.ok;
expect(gutData.events[0].timestamp).to.be.ok;
expect(gutData.events[0].slotid).to.equal(slotId);
expect(gutData.events[0].messageId).to.equal(4);

expect(gutData.slots[0].contentUrl).to
.equal('http://www.getmesomeads.com');
expect(gutData.slots[0].id).to.equal(slotId);
expect(gutData.slots[0].leafAdUnitName).to.equal(slotId);
expect(gutData.slots[0].domId).to.equal(
'gpt_unit_' + slotId + '_0');
expect(gutData.slots[0].creativeId).to.equal('123');
expect(gutData.slots[0].lineItemId).to.equal('456');
},
},
};
const postMessageSpy = sandbox.spy(env.win.opener, 'postMessage');
impl.win = env.win;
return impl.postTroubleshootMessage().then(() =>
expect(postMessageSpy).to.be.calledOnce);
});

it('should not emit post message', () => {
env.win = {
location: {
href: 'http://localhost:8000/foo',
search: '',
},
opener: {
postMessage: () => {
// should never get here
expect(false).to.be.true;
},
},
};
impl.win = env.win;
expect(impl.postTroubleshootMessage()).to.be.null;
});
});
});


Expand Down

0 comments on commit 7867de9

Please sign in to comment.