Skip to content

Commit 8ab0178

Browse files
AnkitSegmentdanieljackinsharsh-joshi99
authored
[STRATCONN-5687] Added support for bing ads consent mode (#822)
* Updated Bing ads consent * Updated Bing ads consent * Updated unit test cases and handle other cases * Updated unit test cases --------- Co-authored-by: Daniel Jackins <djackins@twilio.com> Co-authored-by: Harsh Joshi <harsh.joshi@segment.com>
1 parent 786b989 commit 8ab0178

File tree

6 files changed

+153
-6
lines changed

6 files changed

+153
-6
lines changed

integrations/bing-ads/lib/index.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ Bing.prototype.initialize = function() {
3131
window.uetq = window.uetq || [];
3232
var self = this;
3333

34+
var consent = {
35+
ad_storage: self.options.adStorage || 'denied'
36+
};
37+
if (self.options.enableConsent) {
38+
window.uetq.push('consent', 'default', consent);
39+
}
40+
3441
self.load(function() {
3542
var setup = {
3643
ti: self.options.tagId,
@@ -59,7 +66,11 @@ Bing.prototype.loaded = function() {
5966
* @api public
6067
*/
6168

62-
Bing.prototype.page = function() {
69+
Bing.prototype.page = function(page) {
70+
if (this.options.enableConsent) {
71+
// eslint-disable-next-line no-use-before-define
72+
updateConsent.call(this, page);
73+
}
6374
window.uetq.push('pageLoad');
6475
};
6576

@@ -82,5 +93,35 @@ Bing.prototype.track = function(track) {
8293
if (track.category()) event.ec = track.category();
8394
if (track.revenue()) event.gv = track.revenue();
8495

96+
if (this.options.enableConsent) {
97+
// eslint-disable-next-line no-use-before-define
98+
updateConsent.call(this, track);
99+
}
100+
85101
window.uetq.push(event);
86102
};
103+
104+
function updateConsent(event) {
105+
var consent = {};
106+
107+
// If consent category is granted, set it immediately and return
108+
if (
109+
this.options.consentSettings.categories &&
110+
this.options.consentSettings.categories.includes(
111+
this.options.adStorageConsentCategory
112+
)
113+
) {
114+
consent.ad_storage = 'granted';
115+
window.uetq.push('consent', 'update', consent);
116+
return;
117+
}
118+
119+
// Otherwise, try to get ad_storage value from propertiesPath
120+
var propertiesPath = event.proxy(
121+
'properties.' + this.options.adStoragePropertyMapping
122+
);
123+
if (typeof propertiesPath === 'string') {
124+
consent.ad_storage = propertiesPath.toLowerCase();
125+
window.uetq.push('consent', 'update', consent);
126+
}
127+
}

integrations/bing-ads/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@segment/analytics.js-integration-bing-ads",
33
"description": "The Bing Ads analytics.js integration.",
4-
"version": "2.0.1",
4+
"version": "2.0.2",
55
"keywords": [
66
"analytics.js",
77
"analytics.js-integration",

integrations/bing-ads/test/index.test.js

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ describe('Bing Ads', function() {
1010
var analytics;
1111
var bing;
1212
var options = {
13-
tagId: '4002754'
13+
tagId: '4002754',
14+
enableConsent: true,
15+
adStoragePropertyMapping: '',
16+
adStorage: 'denied',
17+
consentSettings: {
18+
categories: []
19+
}
1420
};
1521

1622
beforeEach(function() {
@@ -44,6 +50,58 @@ describe('Bing Ads', function() {
4450
});
4551
});
4652

53+
describe('#initialize', function() {
54+
beforeEach(function() {
55+
window.uetq = [];
56+
window.UET = function(setup) {
57+
this.ti = setup.ti;
58+
this.q = setup.q;
59+
};
60+
analytics.stub(bing, 'load', function(callback) {
61+
callback();
62+
});
63+
analytics.spy(window.uetq, 'push');
64+
});
65+
66+
afterEach(function() {
67+
// Clean up after each test
68+
delete window.uetq;
69+
});
70+
71+
it('should initialize uetq as an empty array if not already defined', function() {
72+
delete window.uetq;
73+
bing.options.enableConsent = false;
74+
75+
bing.initialize();
76+
77+
analytics.assert(Array.isArray(window.uetq.q));
78+
analytics.assert.deepEqual(window.uetq.q, []);
79+
});
80+
81+
it('should push default consent if enableConsent is true', function() {
82+
bing.options.enableConsent = true;
83+
bing.initialize();
84+
analytics.spy(window.uetq, 'push');
85+
analytics.called(window.uetq.q.push, 'consent', 'default', {
86+
ad_storage: 'denied'
87+
});
88+
});
89+
90+
it('should not push default consent if enableConsent is false', function() {
91+
bing.options.enableConsent = false;
92+
bing.initialize();
93+
analytics.spy(window.uetq, 'push');
94+
analytics.didNotCall(window.uetq.push, 'consent', 'default');
95+
});
96+
97+
it('should call load and set up UET after loading', function() {
98+
bing.initialize();
99+
analytics.called(bing.load);
100+
analytics.assert(window.uetq instanceof window.UET);
101+
analytics.assert.equal(window.uetq.ti, bing.options.tagId);
102+
});
103+
});
104+
47105
describe('after loading', function() {
48106
beforeEach(function(done) {
49107
analytics.once('ready', done);
@@ -75,6 +133,51 @@ describe('Bing Ads', function() {
75133
gv: 90
76134
});
77135
});
136+
137+
it('should not call updateConsent when enable_consent is false', function() {
138+
bing.options.enableConsent = false;
139+
analytics.spy(bing, 'updateConsent');
140+
analytics.track('play', { category: 'fun', revenue: 90 });
141+
analytics.didNotCall(bing.updateConsent);
142+
});
143+
144+
it('should not update consent if ad_storagePropertyMapping is missing', function() {
145+
bing.options.enableConsent = true;
146+
bing.options.adStoragePropertyMapping = '';
147+
analytics.stub(window.uetq, 'push');
148+
analytics.track('purchase', { properties: { ad_storage: 'granted' } });
149+
analytics.didNotCall(window.uetq.push, 'consent', 'update');
150+
});
151+
152+
it('should update consent if adStoragePropertyMapping has value', function() {
153+
bing.options.enableConsent = true;
154+
bing.options.adStoragePropertyMapping = 'ad_storage';
155+
analytics.stub(window.uetq, 'push');
156+
analytics.track('purchase', { ad_storage: 'granted' });
157+
analytics.called(window.uetq.push, 'consent', 'update', {
158+
ad_storage: 'granted'
159+
});
160+
});
161+
162+
it('should update consent based on consentSettings categories', function() {
163+
bing.options.enable_consent = true;
164+
bing.options.consentSettings.categories = ['analytics', 'ads'];
165+
bing.options.adStorageConsentCategory = 'ads';
166+
analytics.stub(window.uetq, 'push');
167+
analytics.track('purchase');
168+
analytics.called(window.uetq.push, 'consent', 'update', {
169+
ad_storage: 'granted'
170+
});
171+
});
172+
173+
it('should not update consent if consentSettings categories do not match', function() {
174+
bing.options.enable_consent = true;
175+
bing.options.consentSettings.categories = ['analytics'];
176+
bing.options.adStorageConsentCategory = 'ads';
177+
analytics.stub(window.uetq, 'push');
178+
analytics.track('purchase');
179+
analytics.didNotCall(window.uetq.push, 'consent', 'update');
180+
});
78181
});
79182
});
80183
});

webpack.config.integrations.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ module.exports = {
4141
chunkFilename: 'vendor/[name].[contenthash].js',
4242
path: path.resolve(__dirname, 'build/integrations'),
4343
library: '[name]Integration',
44-
libraryTarget: 'window'
44+
libraryTarget: 'window',
45+
hashFunction: "sha256"
4546
},
4647
module: {
4748
rules: [

webpack.config.middleware.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ module.exports = {
4040
filename: '[name]/latest/[name].js',
4141
path: path.resolve(__dirname, 'build/middleware'),
4242
library: '[name]Middleware',
43-
libraryTarget: 'umd'
43+
libraryTarget: 'umd',
44+
hashFunction: "sha256"
4445
},
4546
module: {
4647
rules: [

webpack.config.tester.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ module.exports = {
3030
chunkFilename: 'vendor/[name].[contenthash].js.gz',
3131
path: path.resolve(__dirname, 'tester/dist/next-integrations/integrations'),
3232
library: '[name]Integration',
33-
libraryTarget: 'window'
33+
libraryTarget: 'window',
34+
hashFunction: "sha256"
3435
},
3536
module: {
3637
rules: [

0 commit comments

Comments
 (0)