Bug 1161656 - Report total views preceding a click [r=adw]

This commit is contained in:
Maxim Zhilyaev 2015-07-09 23:03:05 -07:00
parent 54694a2200
commit 33bb9e1e0d
3 changed files with 124 additions and 2 deletions

View File

@ -246,6 +246,7 @@ blocked::
{
"id": 702,
"pin": 1,
"past_impressions": {"total": 5, "daily": 1},
},
{},
{
@ -264,6 +265,12 @@ none of the following optional values:
- ``id`` - id that was provided as part of the downloaded link object (for all
types of links: directory, suggested, enhanced); not present if the tile was
created from user behavior, e.g., visiting pages
- ``past_impressions`` - number of impressions (new tab "views") a suggested
tile was shown before it was clicked, pinned or blocked. Where the "total"
counter is the overall number of impressions accumulated prior to a click action,
and "daily" counter is the number impressions occurred on same calendar day of
a click. This infomration is submitted once per a suggested tile upon click,
pin or block
- ``pinned`` - 1 if the tile is pinned; not present otherwise
- ``pos`` - integer position if the tile is not in the natural order, e.g., a
pinned tile after an empty slot; not present otherwise

View File

@ -670,6 +670,7 @@ let DirectoryLinksProvider = {
* @return download promise
*/
reportSitesAction: function DirectoryLinksProvider_reportSitesAction(sites, action, triggeringSiteIndex) {
let pastImpressions;
// Check if the suggested tile was shown
if (action == "view") {
sites.slice(0, triggeringSiteIndex + 1).forEach(site => {
@ -687,6 +688,13 @@ let DirectoryLinksProvider = {
// suggested tile has targetedSite, or frecent_sites if it was pinned
let {frecent_sites, targetedSite, url} = sites[triggeringSiteIndex].link;
if (frecent_sites || targetedSite) {
// skip past_impressions for "unpin" to avoid chance of tracking
if (this._frequencyCaps[url] && action != "unpin") {
pastImpressions = {
total: this._frequencyCaps[url].totalViews,
daily: this._frequencyCaps[url].dailyViews
};
}
this._setFrequencyCapClick(url);
}
}
@ -724,6 +732,7 @@ let DirectoryLinksProvider = {
id: id || site.enhancedId,
pin: site.isPinned() ? 1 : undefined,
pos: pos != tilesIndex ? pos : undefined,
past_impressions: pos == triggeringSiteIndex ? pastImpressions : undefined,
score: Math.round(link.frecency / PING_SCORE_DIVISOR) || undefined,
url: site.enhancedId && "",
});
@ -1321,7 +1330,7 @@ let DirectoryLinksProvider = {
capObject.lastShownDate = Date.now();
}
// bump both dialy and total counters
// bump both daily and total counters
capObject.totalViews++;
capObject.dailyViews++;
@ -1336,7 +1345,7 @@ let DirectoryLinksProvider = {
* Sets clicked flag for link url
* @param url String url of the suggested link
*/
_setFrequencyCapClick: function DirectoryLinksProvider_reportFrequencyCapClick(url) {
_setFrequencyCapClick(url) {
let capObject = this._frequencyCaps[url];
// sanity check
if (!capObject) {

View File

@ -1924,3 +1924,109 @@ add_task(function test_inadjecentSites() {
DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
yield promiseCleanDirectoryLinksProvider();
});
add_task(function test_reportPastImpressions() {
let origGetFrecentSitesName = DirectoryLinksProvider.getFrecentSitesName;
DirectoryLinksProvider.getFrecentSitesName = () => "";
let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
NewTabUtils.isTopPlacesSite = () => true;
let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount;
DirectoryLinksProvider._getCurrentTopSiteCount = () => 8;
let testUrl = "http://frequency.capped/link";
let targets = ["top.site.com"];
let data = {
suggested: [{
type: "affiliate",
frecent_sites: targets,
url: testUrl
}]
};
let dataURI = "data:application/json," + JSON.stringify(data);
yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
// make DirectoryLinksProvider load json
let loadPromise = Promise.defer();
DirectoryLinksProvider.getLinks(_ => {loadPromise.resolve();});
yield loadPromise.promise;
// setup ping handler
let deferred, expectedPath, expectedAction, expectedImpressions;
let done = false;
server.registerPrefixHandler(kPingPath, (aRequest, aResponse) => {
if (done) {
return;
}
do_check_eq(aRequest.path, expectedPath);
let bodyStream = new BinaryInputStream(aRequest.bodyInputStream);
let bodyObject = JSON.parse(NetUtil.readInputStreamToString(bodyStream, bodyStream.available()));
let expectedActionIndex = bodyObject[expectedAction];
if (bodyObject.unpin) {
// unpin should not report past_impressions
do_check_false(bodyObject.tiles[expectedActionIndex].hasOwnProperty("past_impressions"));
}
else if (expectedImpressions) {
do_check_eq(bodyObject.tiles[expectedActionIndex].past_impressions.total, expectedImpressions);
do_check_eq(bodyObject.tiles[expectedActionIndex].past_impressions.daily, expectedImpressions);
}
else {
do_check_eq(expectedPath, "/ping/view");
do_check_false(bodyObject.tiles[expectedActionIndex].hasOwnProperty("past_impressions"));
}
deferred.resolve();
});
// setup ping sender
function sendPingAndTest(path, action, index) {
deferred = Promise.defer();
expectedPath = kPingPath + path;
expectedAction = action;
DirectoryLinksProvider.reportSitesAction(sites, action, index);
return deferred.promise;
}
// Start with a view ping first
let site = {
isPinned: _ => false,
link: {
directoryId: 1,
frecency: 30000,
frecent_sites: targets,
targetedSite: targets[0],
url: testUrl
}
};
let sites = [,
{
isPinned: _ => false,
link: {type: "history", url: "https://foo.com"}
},
site
];
yield sendPingAndTest("view", "view", 2);
yield sendPingAndTest("view", "view", 2);
yield sendPingAndTest("view", "view", 2);
expectedImpressions = DirectoryLinksProvider._frequencyCaps[testUrl].totalViews;
do_check_eq(expectedImpressions, 3);
// now report pin, unpin, block and click
sites.isPinned = _ => true;
yield sendPingAndTest("click", "pin", 2);
sites.isPinned = _ => false;
yield sendPingAndTest("click", "unpin", 2);
sites.isPinned = _ => false;
yield sendPingAndTest("click", "click", 2);
sites.isPinned = _ => false;
yield sendPingAndTest("click", "block", 2);
// Cleanup.
done = true;
DirectoryLinksProvider.getFrecentSitesName = origGetFrecentSitesName;
NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
});