diff --git a/build-system/server.js b/build-system/server.js index 0574190a194db..cf45e0e4acf51 100644 --- a/build-system/server.js +++ b/build-system/server.js @@ -208,7 +208,6 @@ app.use('/share-tracking/get-outgoing-fragment', function(req, res) { function proxyToAmpProxy(req, res, minify) { var url = 'https://cdn.ampproject.org/c' + req.url; var localUrlPrefix = getUrlPrefix(req); - console.log('request request'); request(url, function (error, response, body) { body = body // Unversion URLs. @@ -223,7 +222,7 @@ function proxyToAmpProxy(req, res, minify) { localUrlPrefix + '/dist/v0/'); if (minify) { body = body.replace(/\.max\.js/g, '.js') - .replace('/dist/amp.js', '/dist/v1.js'); + .replace('/dist/amp.js', '/dist/v0.js'); } res.status(response.statusCode).send(body); }); @@ -407,34 +406,20 @@ app.use('/examples/amp-fresh.amp.(min.|max.)?html', function(req, res, next) { app.use('/impression-proxy/', function(req, res) { - //http.get - //console.log('url is ', req.get('impression-proxy')); - //const xhr = assertCors(req, res, ['GET']); - var fakeHeaders = { + const fakeHeaders = { 'Host': 'adclick.g.doubleclick.net', 'Origin': 'https://cdn.ampproject.org', 'Cookie': 'Cookie:id=4903ef7b59596f28||t=1451370221|et=730|cs=002213fd48e4405e4579c95dfa', }; - - var options = { + const options = { url: 'https://googleads.g.doubleclick.net/pcs/click?alp=1&xai=AKAOjstvASJmd6-NeoO3ner8FBNJW2w8n-sXMo0Nj5YC_LIY2NQjbNs0CoXQtM9tPi8by4H4bHRpMdB14qgRLctKkBKkh3vpR3m8fvPCzcFZ6HrxvxXUqzP17YJsihcINtRniOfmGFkzIolJ3ccPSPq6oYdJpg5lPeufOrLhtWsNspOsRgMSBFP7zH0l8tgtAb665jHEFmdAMH1vl69BxpqU2Q0ZoGDO_SVBMArlL--2nLOVgQt8om6IdzkcodppT9c&sig=Cg0ArKJSzEJGKs3-NmXNEAE&urlfix=1&adurl=https://cdn.ampproject.org/c/www.nbcnews.com/news/us-news/amp/milwaukee-cop-cars-smashed-torched-after-police-kill-suspect-n630236', headers: fakeHeaders, }; -// function callback(error, response, body) { -// if (!error && response.statusCode == 200) { -// console.log(body); -// } -// } - request(options, (error, response, body) => { if (!error && response.statusCode == 200) { - console.log(body); res.send(body); - return body; - } else { - console.log(response.statusCode); } }); }); diff --git a/src/impression.js b/src/impression.js index ccf186b55f6b3..bffc0894f7204 100644 --- a/src/impression.js +++ b/src/impression.js @@ -18,7 +18,8 @@ import {user} from './log'; import {isExperimentOn} from './experiments'; import {viewerForDoc} from './viewer'; import {xhrFor} from './xhr'; -import {getMode} from './mode' +import {getMode} from './mode'; +import {openWindowDialog} from './dom'; /** @@ -30,16 +31,13 @@ export function maybeTrackImpression(win) { if (!isExperimentOn(win, 'alp')) { return; } - console.log('aaaaaaa'); + const viewer = viewerForDoc(win.document); /** @const {string|undefined} */ let clickUrl = viewer.getParam('click'); - //clickUrl = 'http://localhost:8000/local-proxy?url=https://googleads.g.doubleclick.net/pcs/click?alp=1&xai=AKAOjstvASJmd6-NeoO3ner8FBNJW2w8n-sXMo0Nj5YC_LIY2NQjbNs0CoXQtM9tPi8by4H4bHRpMdB14qgRLctKkBKkh3vpR3m8fvPCzcFZ6HrxvxXUqzP17YJsihcINtRniOfmGFkzIolJ3ccPSPq6oYdJpg5lPeufOrLhtWsNspOsRgMSBFP7zH0l8tgtAb665jHEFmdAMH1vl69BxpqU2Q0ZoGDO_SVBMArlL--2nLOVgQt8om6IdzkcodppT9c&sig=Cg0ArKJSzEJGKs3-NmXNEAE&urlfix=1&adurl=https://cdn.ampproject.org/c/www.nbcnews.com/news/us-news/amp/milwaukee-cop-cars-smashed-torched-after-police-kill-suspect-n630236'; + // One test clickUrl clickUrl = 'https://googleads.g.doubleclick.net/pcs/click?alp=1&xai=AKAOjstvASJmd6-NeoO3ner8FBNJW2w8n-sXMo0Nj5YC_LIY2NQjbNs0CoXQtM9tPi8by4H4bHRpMdB14qgRLctKkBKkh3vpR3m8fvPCzcFZ6HrxvxXUqzP17YJsihcINtRniOfmGFkzIolJ3ccPSPq6oYdJpg5lPeufOrLhtWsNspOsRgMSBFP7zH0l8tgtAb665jHEFmdAMH1vl69BxpqU2Q0ZoGDO_SVBMArlL--2nLOVgQt8om6IdzkcodppT9c&sig=Cg0ArKJSzEJGKs3-NmXNEAE&urlfix=1&adurl=https://cdn.ampproject.org/c/www.nbcnews.com/news/us-news/amp/milwaukee-cop-cars-smashed-torched-after-police-kill-suspect-n630236'; - //clickUrl = 'https://0.cat2.eventfe.cafe.content-ads-owners.pc.borg.google.com/pcs/click?alp=1&xai=AKAOjstvASJmd6-NeoO3ner8FBNJW2w8n-sXMo0Nj5YC_LIY2NQjbNs0CoXQtM9tPi8by4H4bHRpMdB14qgRLctKkBKkh3vpR3m8fvPCzcFZ6HrxvxXUqzP17YJsihcINtRniOfmGFkzIolJ3ccPSPq6oYdJpg5lPeufOrLhtWsNspOsRgMSBFP7zH0l8tgtAb665jHEFmdAMH1vl69BxpqU2Q0ZoGDO_SVBMArlL--2nLOVgQt8om6IdzkcodppT9c&sig=Cg0ArKJSzEJGKs3-NmXNEAE&urlfix=1&adurl=https://cdn.ampproject.org/c/www.nbcnews.com/news/us-news/amp/milwaukee-cop-cars-smashed-torched-after-police-kill-suspect-n630236'; - //clickUrl = "https%3A%2F%2Fadclick.g.doubleclick.net%2Fpcs%2Fclick%3Famp%3D1%26xai%3DAKAOjsv-m1m4UWV9Ma-712CSL1GAlk8LqQBnsR7qaiMk9RHySNoeynJlw-hKVfH6tWAQSc4_ksp0eIKEpASP9Hg52B1ZQfwZebVkFSw_leOH5LpYrdI8CcKVzdDDahoDwi9BWpxj1hBELNiD2yuq4yKHGqhwmwYAtPLBQSzRoyPJyP5WYjp4YdKMGjDLT_mUmL7zCwbX9FgKNupSIkGoghqLtTIPEdPPd0y-CBN04s3sH9vuUnBD4OdAQ9i0Ty1Lf94KEYo%26sig%3DCg0ArKJSzG321ESes8LKEAE%26urlfix%3D1%26adurl%3Dhttps%3A%2F%2Fcdn.ampproject.org%2Fc%2Fs%2Fwww.buzzfeed.com%2Famphtml%2Fstephaniemcneal%2Fyou-can-use-this-website-to-make-president-obama-say-whateve"; - //clickUrl = 'https://googleads.g.doubleclick.net/pcs/click?alp=1&xai=abc…&sig=xyz…&adurl=https://cdn.ampproject.org/c/events.latimes.com/festivalofbooks/&nm=3&nx=139&ny=132&mb=33&clkt=2'; if (!clickUrl) { return; } @@ -55,22 +53,72 @@ export function maybeTrackImpression(win) { // avoid duplicate tracking. win.location.hash = ''; } - if (getMode().localDev) { - clickUrl = 'http://localhost:8000/impression-proxy?url=' + clickUrl; - } + viewer.whenFirstVisible().then(() => { - invoke(win, clickUrl); + // TODO(@zhouyx) We need a timeout here? + // TODO(@zhouyx) need test with a real response. + invoke(win, clickUrl).then(response => { + if (!response) { + return; + } + applyResponse(win, viewer, response); + }); }); } +/** + * Send the url to ad server and wait for its response + * @param {!Window} win + * @param {string} clickUrl + * @return {!Promise} + */ function invoke(win, clickUrl) { - xhrFor(win).fetchJson(clickUrl, { + if (getMode().localDev && !getMode().test) { + clickUrl = 'http://localhost:8000/impression-proxy?url=' + clickUrl; + } + return xhrFor(win).fetchJson(clickUrl, { credentials: 'include', requireAmpResponseSourceOrigin: true, - }).then(a => { - console.log('fetchJson return'); - console.log(a); }); - console.log('invoke'); // TODO(@cramforce): Do something with the result. } + +/** + * parse the response back from ad server + * Set for analytics purposes + * @param {!Window} win + * @param {!Object} response + */ +function applyResponse(win, viewer, response) { + const adLocation = response['location']; + + // If there's a tracking_url, need to redirect to that url. + const adTrackingUrl = response['tracking_url']; + if (adTrackingUrl) { + // TODO(@zhouyx) Confirm we assume the tracking_url is not + // a cdn.ampproject page, and we don't do viewer redirect + openWindowDialog(win, adTrackingUrl, '_top'); + return; + } + + // If adLocation is not an amp page, need to redirect to it. + if (adLocation && adLocation.indexOf('https://cdn.ampproject.org') != 0) { + // TODO(@zhouyx) Confirm we assume the tracking_url is not + // a cdn.ampproject page, and we don't do viewer redirect + openWindowDialog(win, adLocation, '_top'); + return; + } + + // If have gclid, or location contains gclid. add it to location hash + // Set gclid. + // If provided use it, if not try to find in adLocation from response + let gclid = response['gclid']; + if (!gclid) { + if (adLocation.indexOf('gclid=') > 0) { + gclid = adLocation.substr(adLocation.indexOf('gclid=') + 6); + } + } + if (gclid) { + win.location.hash = '#gclid=' + gclid; + } +} diff --git a/src/service/xhr-impl.js b/src/service/xhr-impl.js index 03de15fc22ab1..6058fdfe4794d 100644 --- a/src/service/xhr-impl.js +++ b/src/service/xhr-impl.js @@ -162,9 +162,7 @@ export class Xhr { const init = opt_init || {}; init.method = normalizeMethod_(init.method); setupJson_(init); - console.log('in fetchJson'); return this.fetchAmpCors_(input, init).then(response => { - console.log('fetch response is ', response); return assertSuccess(response); }).then(response => response.json()); } diff --git a/test/functional/test-impression.js b/test/functional/test-impression.js index 50581b5e47ec0..74d419d4b37b5 100644 --- a/test/functional/test-impression.js +++ b/test/functional/test-impression.js @@ -18,6 +18,7 @@ import {maybeTrackImpression} from '../../src/impression'; import {toggleExperiment} from '../../src/experiments'; import {viewerForDoc} from '../../src/viewer'; import {xhrFor} from '../../src/xhr'; +import * as dom from '../../src/dom'; import * as sinon from 'sinon'; describe('impression', () => { @@ -80,4 +81,95 @@ describe('impression', () => { }); }); }); + + it('should redirect if xhr return tracking url', () => { + toggleExperiment(window, 'alp', true); + viewer.getParam.withArgs('click').returns('https://www.example.com'); + + const openWindowDialogSpy = sandbox.stub(dom, 'openWindowDialog', + (win, url, target) => { + expect(url).to.equal('test_tracking_url'); + expect(target).to.equal('_top'); + }); + + xhr.fetchJson = () => { + return Promise.resolve({ + 'location': 'test_location', + 'tracking_url': 'test_tracking_url', + }); + }; + + maybeTrackImpression(window); + return Promise.resolve().then(() => { + return Promise.resolve().then(() => { + expect(openWindowDialogSpy).to.be.calledOnce; + }); + }); + }); + + it('should redirect if location is some other url', () => { + toggleExperiment(window, 'alp', true); + viewer.getParam.withArgs('click').returns('https://www.example.com'); + + const openWindowDialogSpy = sandbox.stub(dom, 'openWindowDialog', + (win, url, target) => { + expect(url).to.equal('test_location'); + expect(target).to.equal('_top'); + }); + + xhr.fetchJson = () => { + return Promise.resolve({ + 'location': 'test_location', + }); + }; + + maybeTrackImpression(window); + return Promise.resolve().then(() => { + return Promise.resolve().then(() => { + expect(openWindowDialogSpy).to.be.calledOnce; + }); + }); + }); + + it('should not redirect if location is valid', () => { + toggleExperiment(window, 'alp', true); + viewer.getParam.withArgs('click').returns('https://www.example.com'); + + const openWindowDialogSpy = sandbox.spy(dom, 'openWindowDialog'); + + xhr.fetchJson = () => { + return Promise.resolve({ + 'location': 'https://cdn.ampproject.org/c/test/?gclid=654321', + }); + }; + + maybeTrackImpression(window); + return Promise.resolve().then(() => { + return Promise.resolve().then(() => { + expect(openWindowDialogSpy).to.not.be.called; + expect(window.location.hash).to.equal('#gclid=654321'); + }); + }); + }); + + it('should set gclid to location hash', () => { + toggleExperiment(window, 'alp', true); + viewer.getParam.withArgs('click').returns('https://www.example.com'); + + const openWindowDialogSpy = sandbox.spy(dom, 'openWindowDialog'); + + xhr.fetchJson = () => { + return Promise.resolve({ + 'gclid': '123456', + }); + }; + + maybeTrackImpression(window); + return Promise.resolve().then(() => { + return Promise.resolve().then(() => { + expect(openWindowDialogSpy).to.not.be.called; + expect(window.location.hash).to.be.equal('#gclid=123456'); + }); + }); + }); });