commit f10ae21e5ae408e01f7140469f09e4cc87b42d0a
parent 3dc471cd51b135d36a303909302c6cb2b13768f3
Author: Nathan Barrett <nbarrett@mozilla.com>
Date: Fri, 9 Jan 2026 21:38:06 +0000
Bug 2006377 - Retreive task object from new partner_id endpoint r=home-newtab-reviewers,mconley
Differential Revision: https://phabricator.services.mozilla.com/D276683
Diffstat:
5 files changed, 225 insertions(+), 215 deletions(-)
diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
@@ -681,7 +681,7 @@ pref("browser.urlbar.merino.ohttpConfigURL", "");
pref("browser.urlbar.merino.ohttpRelayURL", "");
// OHTTP hpke for DAP
-pref("dap.ohttp.hpke", "https://dap-09-3.api.divviup.org/ohttp-configs");
+pref("dap.ohttp.hpke", "gAAgJSO22Y3HKzRSese15JtQVuuFfOIcTrZ56lQ5kDQwS0oABAABAAE");
// OHTTP relay URL for DAP
pref("dap.ohttp.relayURL", "https://mozilla-ohttp-dap.mozilla.fastly-edge.com/");
diff --git a/browser/extensions/newtab/content-src/components/DiscoveryStreamAdmin/DiscoveryStreamAdmin.jsx b/browser/extensions/newtab/content-src/components/DiscoveryStreamAdmin/DiscoveryStreamAdmin.jsx
@@ -363,7 +363,7 @@ export class DiscoveryStreamAdminUI extends React.PureComponent {
sendConversionEvent() {
const detail = {
- partnerId: "demo-partner",
+ partnerId: "295BEEF7-1E3B-4128-B8F8-858E12AA660B",
lookbackDays: 7,
impressionType: "default",
};
diff --git a/browser/extensions/newtab/data/content/activity-stream.bundle.js b/browser/extensions/newtab/data/content/activity-stream.bundle.js
@@ -893,7 +893,7 @@ class DiscoveryStreamAdminUI extends (external_React_default()).PureComponent {
}
sendConversionEvent() {
const detail = {
- partnerId: "demo-partner",
+ partnerId: "295BEEF7-1E3B-4128-B8F8-858E12AA660B",
lookbackDays: 7,
impressionType: "default"
};
diff --git a/browser/extensions/newtab/lib/NewTabAttributionService.sys.mjs b/browser/extensions/newtab/lib/NewTabAttributionService.sys.mjs
@@ -8,15 +8,23 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
IndexedDB: "resource://gre/modules/IndexedDB.sys.mjs",
DAPSender: "resource://gre/modules/DAPSender.sys.mjs",
+ ObliviousHTTP: "resource://gre/modules/ObliviousHTTP.sys.mjs",
+ HPKEConfigManager: "resource://gre/modules/HPKEConfigManager.sys.mjs",
});
-const MAX_CONVERSIONS = 5;
+const MAX_CONVERSIONS = 2;
const MAX_LOOKBACK_DAYS = 30;
const DAY_IN_MILLI = 1000 * 60 * 60 * 24;
const CONVERSION_RESET_MILLI = 7 * DAY_IN_MILLI;
const DAP_HPKE_PREF = "dap.ohttp.hpke";
const DAP_RELAY_PREF = "dap.ohttp.relayURL";
+const MARS_ENDPOINT_PREF =
+ "browser.newtabpage.activity-stream.unifiedAds.endpoint";
+const PREF_MARS_OHTTP_CONFIG =
+ "browser.newtabpage.activity-stream.discoverystream.ohttp.configURL";
+const PREF_MARS_OHTTP_RELAY =
+ "browser.newtabpage.activity-stream.discoverystream.ohttp.relayURL";
/**
*
@@ -30,7 +38,6 @@ class NewTabAttributionService {
* @typedef {object} task - DAP task settings.
* @property {string} id - task id.
* @property {string} vdaf - vdaf type.
- * @property {number} bits - datatype size.
* @property {number} length - number of buckets.
* @property {number} time_precision - time precision.
*
@@ -90,39 +97,26 @@ class NewTabAttributionService {
try {
const now = this.#now();
- const impressionStore = await this.#getImpressionStore();
-
- if (!params || !params.conversion) {
+ if (
+ !params ||
+ !params.partner_id ||
+ params.index === undefined ||
+ params.index === null
+ ) {
return;
}
- const impression = await this.#getImpression(
- impressionStore,
- params.partner_id,
- {
- conversion: {
- task: {
- id: params.conversion.task_id,
- vdaf: params.conversion.vdaf,
- bits: params.conversion.bits,
- length: params.conversion.length,
- time_precision: params.conversion.time_precision,
- },
- defaultMeasurement: params.conversion.default_measurement,
- index: params.conversion.index,
- },
- }
- );
+ const impression = await this.#getImpression(params.partner_id, {
+ conversion: {
+ index: params.index,
+ },
+ });
const prop = this.#getModelProp(type);
impression.lastImpression = now;
impression[prop] = now;
- await this.#updateImpression(
- impressionStore,
- params.partner_id,
- impression
- );
+ await this.#updateImpression(params.partner_id, impression);
} catch (e) {
console.error(e);
}
@@ -178,9 +172,10 @@ class NewTabAttributionService {
if (lookbackDays > MAX_LOOKBACK_DAYS) {
return;
}
+ // we don't want to request the gateway key at time of conversion to avoid an IP address leak
const dapHpke = Services.prefs.getCharPref(
DAP_HPKE_PREF,
- "https://dap-09-3.api.divviup.org/ohttp-configs"
+ "gAAgJSO22Y3HKzRSese15JtQVuuFfOIcTrZ56lQ5kDQwS0oABAABAAE"
);
const ohttpRelayURL = Services.prefs.getCharPref(
DAP_RELAY_PREF,
@@ -196,21 +191,28 @@ class NewTabAttributionService {
now
);
- let conversion = impression?.conversion;
- if (!conversion) {
- // retreive "conversion" for conversions with no found impression
- // conversion = await this.#getUnattributedTask(partnerId);
- if (!conversion) {
- return;
- }
+ const receivedTaskConfig = await this.#getTaskConfig(partnerId);
+
+ if (!receivedTaskConfig) {
+ return;
}
- let measurement = conversion.defaultMeasurement;
+ // Need to rename task_id to id for DAP report submission.
+ const taskConfig = {
+ ...receivedTaskConfig,
+ id: receivedTaskConfig.task_id,
+ };
+
+ let measurement = receivedTaskConfig.default_measurement;
let budgetSpend = 0;
- if (budget.conversions < MAX_CONVERSIONS && conversion) {
+ if (budget.conversions < MAX_CONVERSIONS && impression) {
budgetSpend = 1;
- if (conversion.task && conversion.task.length > conversion.index) {
- measurement = conversion.index;
+ const conversionIndex = impression.conversion.index;
+ if (
+ receivedTaskConfig.length > conversionIndex &&
+ conversionIndex !== undefined
+ ) {
+ measurement = conversionIndex;
}
}
@@ -218,7 +220,7 @@ class NewTabAttributionService {
const options = {};
if (dapHpke) {
- options.ohttp_hpke = dapHpke;
+ options.ohttp_hpke = lazy.HPKEConfigManager.decodeKey(dapHpke);
}
if (ohttpRelayURL) {
@@ -226,7 +228,7 @@ class NewTabAttributionService {
}
await this.#dapSender.sendDAPMeasurement(
- conversion.task,
+ taskConfig,
measurement,
options
);
@@ -278,12 +280,12 @@ class NewTabAttributionService {
* if it is found, defaulting to the passed in impression if there are none. This
* enables timestamp fields of the stored event to be updated or carried forward.
*
- * @param {ObjectStore} impressionStore - Promise-based wrapped IDBObjectStore.
* @param {string} partnerId - partner this event is associated with.
* @param {impression} defaultImpression - event to use if it has not been seen previously.
* @returns {Promise<impression>}
*/
- async #getImpression(impressionStore, partnerId, defaultImpression) {
+ async #getImpression(partnerId, defaultImpression) {
+ const impressionStore = await this.#getImpressionStore();
const impressions = await this.#getPartnerImpressions(
impressionStore,
partnerId
@@ -295,15 +297,60 @@ class NewTabAttributionService {
return impression ?? defaultImpression;
}
+ async #getTaskConfig(partnerId) {
+ const baseUrl = Services.prefs.getCharPref(MARS_ENDPOINT_PREF, "");
+ const endpoint = `${baseUrl}/v1/attribution?partner_id=${encodeURIComponent(
+ partnerId
+ )}`;
+ const ohttpConfigURL = Services.prefs.getCharPref(
+ PREF_MARS_OHTTP_CONFIG,
+ ""
+ );
+ const ohttpRelayURL = Services.prefs.getCharPref(PREF_MARS_OHTTP_RELAY, "");
+
+ if (!partnerId || !endpoint || !ohttpRelayURL || !ohttpConfigURL) {
+ return null;
+ }
+ const controller = new AbortController();
+ const { signal } = controller;
+ let config = await lazy.ObliviousHTTP.getOHTTPConfig(ohttpConfigURL);
+ if (!config) {
+ console.error(
+ new Error(
+ `OHTTP was configured for ${endpoint} but we couldn't fetch a valid config`
+ )
+ );
+ return null;
+ }
+ try {
+ const response = await lazy.ObliviousHTTP.ohttpRequest(
+ ohttpRelayURL,
+ config,
+ endpoint,
+ {
+ headers: {},
+ signal,
+ }
+ );
+ return response.json();
+ } catch (error) {
+ console.error(
+ `Failed to make OHTTP request for unattributed task: ${error.message}`,
+ error
+ );
+ return null;
+ }
+ }
+
/**
* updateImpression stores the passed event, either updating the record
* if this event was already seen, or appending to the list of events if it is new.
*
- * @param {ObjectStore} impressionStore - Promise-based wrapped IDBObjectStore.
* @param {string} partnerId - partner this event is associated with.
* @param {impression} impression - event to update.
*/
- async #updateImpression(impressionStore, partnerId, impression) {
+ async #updateImpression(partnerId, impression) {
+ const impressionStore = await this.#getImpressionStore();
let impressions = await this.#getPartnerImpressions(
impressionStore,
partnerId
@@ -324,13 +371,10 @@ class NewTabAttributionService {
/**
* @param {impression} cur
* @param {impression} impression
- * @returns {boolean} true if cur and impression have the same DAP allocation, else false.
+ * @returns {boolean} true if cur and impression have the same index
*/
#compareImpression(cur, impression) {
- return (
- cur.conversion.task.id === impression.conversion.task.id &&
- cur.conversion.index === impression.conversion.index
- );
+ return cur.conversion.index === impression.conversion.index;
}
/**
diff --git a/browser/extensions/newtab/test/xpcshell/test_NewTabAttributionService.js b/browser/extensions/newtab/test/xpcshell/test_NewTabAttributionService.js
@@ -6,6 +6,8 @@ https://creativecommons.org/publicdomain/zero/1.0/ */
ChromeUtils.defineESModuleGetters(this, {
NewTabAttributionServiceClass:
"resource://newtab/lib/NewTabAttributionService.sys.mjs",
+ ObliviousHTTP: "resource://gre/modules/ObliviousHTTP.sys.mjs",
+ sinon: "resource://testing-common/Sinon.sys.mjs",
});
const { HttpServer } = ChromeUtils.importESModule(
@@ -21,7 +23,7 @@ const BinaryInputStream = Components.Constructor(
const PREF_LEADER = "toolkit.telemetry.dap.leader.url";
const PREF_HELPER = "toolkit.telemetry.dap.helper.url";
const TASK_ID = "DSZGMFh26hBYXNaKvhL_N4AHA3P5lDn19on1vFPBxJM";
-const MAX_CONVERSIONS = 5;
+const MAX_CONVERSIONS = 2;
const DAY_IN_MILLI = 1000 * 60 * 60 * 24;
const LOOKBACK_DAYS = 1;
const MAX_LOOKBACK_DAYS = 30;
@@ -100,8 +102,52 @@ class MockServer {
}
}
+let globalSandbox;
+
add_setup(async function () {
do_get_profile();
+ Services.prefs.setStringPref(
+ "browser.newtabpage.activity-stream.unifiedAds.endpoint",
+ "https://test.example.com"
+ );
+ Services.prefs.setStringPref(
+ "browser.newtabpage.activity-stream.discoverystream.ohttp.configURL",
+ "https://test.example.com/config"
+ );
+ Services.prefs.setStringPref(
+ "browser.newtabpage.activity-stream.discoverystream.ohttp.relayURL",
+ "https://test.example.com/relay"
+ );
+
+ globalSandbox = sinon.createSandbox();
+ globalSandbox.stub(ObliviousHTTP, "getOHTTPConfig").resolves({});
+ globalSandbox.stub(ObliviousHTTP, "ohttpRequest").resolves({
+ status: 200,
+ json: () => {
+ return Promise.resolve({
+ task_id: TASK_ID,
+ vdaf: "histogram",
+ bits: 1,
+ length: HISTOGRAM_SIZE,
+ time_precision: 60,
+ default_measurement: 0,
+ });
+ },
+ });
+});
+
+registerCleanupFunction(() => {
+ Services.prefs.clearUserPref(
+ "browser.newtabpage.activity-stream.unifiedAds.endpoint"
+ );
+ Services.prefs.clearUserPref(
+ "browser.newtabpage.activity-stream.discoverystream.ohttp.configURL"
+ );
+ Services.prefs.clearUserPref(
+ "browser.newtabpage.activity-stream.discoverystream.ohttp.relayURL"
+ );
+
+ globalSandbox.restore();
});
add_task(async function testSuccessfulConversion() {
@@ -111,24 +157,56 @@ add_task(async function testSuccessfulConversion() {
});
const partnerIdentifier = "partner_identifier";
- const conversionSettings = {
+ const index = 1;
+
+ await privateAttribution.onAttributionEvent("view", {
+ partner_id: partnerIdentifier,
+ index,
+ });
+
+ await privateAttribution.onAttributionEvent("click", {
+ partner_id: partnerIdentifier,
+ index,
+ });
+
+ await privateAttribution.onAttributionConversion(
+ partnerIdentifier,
+ LOOKBACK_DAYS,
+ "view"
+ );
+
+ const receivedMeasurement = mockSender.receivedMeasurements.pop();
+ Assert.deepEqual(receivedMeasurement.task, {
task_id: TASK_ID,
+ id: TASK_ID,
vdaf: "histogram",
bits: 1,
length: HISTOGRAM_SIZE,
time_precision: 60,
default_measurement: 0,
- index: 1,
- };
+ });
+ Assert.equal(receivedMeasurement.measurement, index);
+ Assert.ok(receivedMeasurement.options.ohttp_hpke);
+ Assert.equal(receivedMeasurement.options.ohttp_hpke.length, 41);
+ Assert.equal(
+ receivedMeasurement.options.ohttp_relay,
+ Services.prefs.getStringPref("dap.ohttp.relayURL")
+ );
+ Assert.equal(mockSender.receivedMeasurements.length, 0);
+});
- await privateAttribution.onAttributionEvent("view", {
- partner_id: partnerIdentifier,
- conversion: conversionSettings,
+add_task(async function testZeroIndex() {
+ const mockSender = new MockDAPSender();
+ const privateAttribution = new NewTabAttributionServiceClass({
+ dapSender: mockSender,
});
- await privateAttribution.onAttributionEvent("click", {
+ const partnerIdentifier = "partner_identifier_zero";
+ const index = 0;
+
+ await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier,
- conversion: conversionSettings,
+ index,
});
await privateAttribution.onAttributionConversion(
@@ -137,23 +215,8 @@ add_task(async function testSuccessfulConversion() {
"view"
);
- const expectedMeasurement = {
- task: {
- id: conversionSettings.task_id,
- vdaf: conversionSettings.vdaf,
- bits: conversionSettings.bits,
- length: conversionSettings.length,
- time_precision: conversionSettings.time_precision,
- },
- measurement: conversionSettings.index,
- options: {
- ohttp_hpke: Services.prefs.getStringPref("dap.ohttp.hpke"),
- ohttp_relay: Services.prefs.getStringPref("dap.ohttp.relayURL"),
- },
- };
-
const receivedMeasurement = mockSender.receivedMeasurements.pop();
- Assert.deepEqual(receivedMeasurement, expectedMeasurement);
+ Assert.equal(receivedMeasurement.measurement, index);
Assert.equal(mockSender.receivedMeasurements.length, 0);
});
@@ -171,6 +234,17 @@ add_task(async function testConversionWithoutImpression() {
"view"
);
+ const receivedMeasurement = mockSender.receivedMeasurements.pop();
+ Assert.deepEqual(receivedMeasurement.task, {
+ task_id: TASK_ID,
+ id: TASK_ID,
+ vdaf: "histogram",
+ bits: 1,
+ length: HISTOGRAM_SIZE,
+ time_precision: 60,
+ default_measurement: 0,
+ });
+ Assert.equal(receivedMeasurement.measurement, 0);
Assert.equal(mockSender.receivedMeasurements.length, 0);
});
@@ -181,19 +255,11 @@ add_task(async function testConversionWithInvalidLookbackDays() {
});
const partnerIdentifier = "partner_identifier";
- const conversionSettings = {
- task_id: TASK_ID,
- vdaf: "histogram",
- bits: 1,
- length: HISTOGRAM_SIZE,
- time_precision: 60,
- default_measurement: 0,
- index: 1,
- };
+ const index = 1;
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier,
- conversion: conversionSettings,
+ index,
});
await privateAttribution.onAttributionConversion(
@@ -214,15 +280,6 @@ add_task(async function testSelectionByLastView() {
});
const partnerIdentifier = "partner_identifier_last_view";
- const conversionSettings = {
- task_id: TASK_ID,
- vdaf: "histogram",
- bits: 1,
- length: HISTOGRAM_SIZE,
- time_precision: 60,
- default_measurement: 0,
- index: 1,
- };
const selectedViewIndex = 1;
const ignoredViewIndex = 2;
const clickIndex = 3;
@@ -230,10 +287,7 @@ add_task(async function testSelectionByLastView() {
// View event that will be ignored, as a more recent view will exist
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier,
- conversion: {
- ...conversionSettings,
- index: ignoredViewIndex,
- },
+ index: ignoredViewIndex,
});
// step forward time
@@ -242,10 +296,7 @@ add_task(async function testSelectionByLastView() {
// View event that will be selected, as no more recent view exists
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier,
- conversion: {
- ...conversionSettings,
- index: selectedViewIndex,
- },
+ index: selectedViewIndex,
});
// step forward time
@@ -254,10 +305,7 @@ add_task(async function testSelectionByLastView() {
// Click event that will be ignored because the match type is "view"
await privateAttribution.onAttributionEvent("click", {
partner_id: partnerIdentifier,
- conversion: {
- ...conversionSettings,
- index: clickIndex,
- },
+ index: clickIndex,
});
// Conversion filtering for "view" finds the view event
@@ -281,15 +329,6 @@ add_task(async function testSelectionByLastClick() {
});
const partnerIdentifier = "partner_identifier_last_click";
- const conversionSettings = {
- task_id: TASK_ID,
- vdaf: "histogram",
- bits: 1,
- length: HISTOGRAM_SIZE,
- time_precision: 60,
- default_measurement: 0,
- index: 1,
- };
const viewIndex = 1;
const ignoredClickIndex = 2;
const selectedClickIndex = 3;
@@ -297,10 +336,7 @@ add_task(async function testSelectionByLastClick() {
// Click event that will be ignored, as a more recent click will exist
await privateAttribution.onAttributionEvent("click", {
partner_id: partnerIdentifier,
- conversion: {
- ...conversionSettings,
- index: ignoredClickIndex,
- },
+ index: ignoredClickIndex,
});
// step forward time
@@ -309,10 +345,7 @@ add_task(async function testSelectionByLastClick() {
// Click event that will be selected, as no more recent click exists
await privateAttribution.onAttributionEvent("click", {
partner_id: partnerIdentifier,
- conversion: {
- ...conversionSettings,
- index: selectedClickIndex,
- },
+ index: selectedClickIndex,
});
// step forward time
@@ -321,10 +354,7 @@ add_task(async function testSelectionByLastClick() {
// View event that will be ignored because the match type is "click"
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier,
- conversion: {
- ...conversionSettings,
- index: viewIndex,
- },
+ index: viewIndex,
});
// Conversion filtering for "click" finds the click event
@@ -348,25 +378,13 @@ add_task(async function testSelectionByLastTouch() {
});
const partnerIdentifier = "partner_identifier_last_touch";
- const conversionSettings = {
- task_id: TASK_ID,
- vdaf: "histogram",
- bits: 1,
- length: HISTOGRAM_SIZE,
- time_precision: 60,
- default_measurement: 0,
- index: 1,
- };
const viewIndex = 1;
const clickIndex = 2;
// Click at clickIndex
await privateAttribution.onAttributionEvent("click", {
partner_id: partnerIdentifier,
- conversion: {
- ...conversionSettings,
- index: clickIndex,
- },
+ index: clickIndex,
});
// step forward time so the view event occurs most recently
@@ -375,10 +393,7 @@ add_task(async function testSelectionByLastTouch() {
// View at viewIndex
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier,
- conversion: {
- ...conversionSettings,
- index: viewIndex,
- },
+ index: viewIndex,
});
// Conversion filtering for "default" finds the view event
@@ -403,25 +418,13 @@ add_task(async function testSelectionByPartnerId() {
const partnerIdentifier1 = "partner_identifier_1";
const partnerIdentifier2 = "partner_identifier_2";
- const conversionSettings = {
- task_id: TASK_ID,
- vdaf: "histogram",
- bits: 1,
- length: HISTOGRAM_SIZE,
- time_precision: 60,
- default_measurement: 0,
- index: 1,
- };
const partner1Index = 1;
const partner2Index = 2;
// view event associated with partner 1
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier1,
- conversion: {
- ...conversionSettings,
- index: partner1Index,
- },
+ index: partner1Index,
});
// step forward time so the partner 2 event occurs most recently
@@ -430,10 +433,7 @@ add_task(async function testSelectionByPartnerId() {
// view event associated with partner 2
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier2,
- conversion: {
- ...conversionSettings,
- index: partner2Index,
- },
+ index: partner2Index,
});
// Conversion filtering for "default" finds the correct view event
@@ -457,32 +457,26 @@ add_task(async function testExpiredImpressions() {
});
const partnerIdentifier = "partner_identifier";
- const conversionSettings = {
- task_id: TASK_ID,
- vdaf: "histogram",
- bits: 1,
- length: HISTOGRAM_SIZE,
- time_precision: 60,
- default_measurement: 0,
- index: 1,
- };
+ const index = 1;
+ const defaultMeasurement = 0;
// Register impression
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier,
- conversion: conversionSettings,
+ index,
});
// Fast-forward time by LOOKBACK_DAYS days + 1 ms
mockDateProvider.add(LOOKBACK_DAYS * DAY_IN_MILLI + 1);
- // Conversion doesn't match expired impression
await privateAttribution.onAttributionConversion(
partnerIdentifier,
LOOKBACK_DAYS,
"view"
);
+ const receivedMeasurement = mockSender.receivedMeasurements.pop();
+ Assert.deepEqual(receivedMeasurement.measurement, defaultMeasurement);
Assert.equal(mockSender.receivedMeasurements.length, 0);
});
@@ -493,19 +487,12 @@ add_task(async function testConversionBudget() {
});
const partnerIdentifier = "partner_identifier_budget";
- const conversionSettings = {
- task_id: TASK_ID,
- vdaf: "histogram",
- bits: 1,
- length: HISTOGRAM_SIZE,
- time_precision: 60,
- default_measurement: 0,
- index: 1,
- };
+ const index = 1;
+ const defaultMeasurement = 0;
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier,
- conversion: conversionSettings,
+ index,
});
// Measurements uploaded for conversions up to MAX_CONVERSIONS
@@ -517,7 +504,7 @@ add_task(async function testConversionBudget() {
);
const receivedMeasurement = mockSender.receivedMeasurements.pop();
- Assert.deepEqual(receivedMeasurement.measurement, conversionSettings.index);
+ Assert.deepEqual(receivedMeasurement.measurement, index);
Assert.equal(mockSender.receivedMeasurements.length, 0);
}
@@ -529,10 +516,7 @@ add_task(async function testConversionBudget() {
);
const receivedMeasurement = mockSender.receivedMeasurements.pop();
- Assert.deepEqual(
- receivedMeasurement.measurement,
- conversionSettings.default_measurement
- );
+ Assert.deepEqual(receivedMeasurement.measurement, defaultMeasurement);
Assert.equal(mockSender.receivedMeasurements.length, 0);
});
@@ -543,20 +527,13 @@ add_task(async function testHistogramSize() {
});
const partnerIdentifier = "partner_identifier_bad_settings";
- const conversionSettings = {
- task_id: TASK_ID,
- vdaf: "histogram",
- bits: 1,
- length: HISTOGRAM_SIZE,
- time_precision: 60,
- default_measurement: 0,
- // Zero-based index equal to histogram size is out of bounds
- index: HISTOGRAM_SIZE,
- };
+ const defaultMeasurement = 0;
+ // Zero-based index equal to histogram size is out of bounds
+ const index = HISTOGRAM_SIZE;
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier,
- conversion: conversionSettings,
+ index,
});
await privateAttribution.onAttributionConversion(
@@ -566,10 +543,7 @@ add_task(async function testHistogramSize() {
);
const receivedMeasurement = mockSender.receivedMeasurements.pop();
- Assert.deepEqual(
- receivedMeasurement.measurement,
- conversionSettings.default_measurement
- );
+ Assert.deepEqual(receivedMeasurement.measurement, defaultMeasurement);
Assert.equal(mockSender.receivedMeasurements.length, 0);
});
@@ -584,19 +558,11 @@ add_task(async function testWithRealDAPSender() {
const privateAttribution = new NewTabAttributionServiceClass();
const partnerIdentifier = "partner_identifier_real_dap";
- const conversionSettings = {
- task_id: TASK_ID,
- vdaf: "histogram",
- bits: 1,
- length: HISTOGRAM_SIZE,
- time_precision: 60,
- default_measurement: 0,
- index: 1,
- };
+ const index = 1;
await privateAttribution.onAttributionEvent("view", {
partner_id: partnerIdentifier,
- conversion: conversionSettings,
+ index,
});
await privateAttribution.onAttributionConversion(