From 6f544a8b3793837260d0dfcc310c9ca91818c04f Mon Sep 17 00:00:00 2001
From: Gaurav Kochar <gaurav.kochar@segment.com>
Date: Mon, 26 Feb 2024 17:36:26 +0530
Subject: [PATCH 1/4] Worked on adding consent signal in Google tag

---
 integrations/google-adwords-new/lib/index.js  | 27 +++++++++
 .../google-adwords-new/test/index.test.js     | 58 +++++++++++++++++--
 2 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/integrations/google-adwords-new/lib/index.js b/integrations/google-adwords-new/lib/index.js
index 39317b99f..651aa12db 100644
--- a/integrations/google-adwords-new/lib/index.js
+++ b/integrations/google-adwords-new/lib/index.js
@@ -9,6 +9,7 @@ var each = require('@ndhoule/each');
 var find = require('obj-case');
 var reject = require('reject');
 var extend = require('extend');
+const UNSPECIFIED='unspecified';
 
 /**
  * Expose `GoogleAdWordsNew` integration.
@@ -23,6 +24,12 @@ var GoogleAdWordsNew = (module.exports = integration('Google AdWords New')
   .option('defaultPageConversion', '')
   .option('disableAdPersonalization', false)
   .option('floodlightAccountId', '')
+  .option('enableConsentMode',false)
+  .option('adUserDataConsentState')
+  .option('adPersonalizationConsentState')
+  .option('defaultAdsStorageConsentState')
+  .option('defaultAnalyticsStorageConsentState')
+  .option('waitTimeToUpdateConsentStage')
   // The ID in this line (i.e. the gtag.js ID) does not determine which account(s) will receive data from the tag; rather, it is used to uniquely identify your global site tag. Which account(s) receive data from the tag is determined by calling the config command (and by using the send_to parameter on an event). For instance, if you use Google Analytics, you may already have the gtag.js global site tag installed on your site. In that case, the gtag.js ID may be that of the Google Analytics property where you first obtained the snippet.
   .tag(
     '<script src="https://www.googletagmanager.com/gtag/js?id={{ accountId }}">'
@@ -61,6 +68,26 @@ GoogleAdWordsNew.prototype.initialize = function() {
     }
     window.gtag('config', self.options.accountId, config);
 
+    if (self.options.enableConsentMode) {
+     let consent={};
+          if(self.options.adUserDataConsentState && self.options.adUserDataConsentState!=UNSPECIFIED){
+            consent.ad_user_data = self.options.adUserDataConsentState
+          }
+          if(self.options.adPersonalizationConsentState && self.options.adPersonalizationConsentState!=UNSPECIFIED){
+            consent.ad_personalization = self.options.adPersonalizationConsentState
+          }
+          if(self.options.defaultAdsStorageConsentState && self.options.defaultAdsStorageConsentState!=UNSPECIFIED){
+            consent.ad_storage = self.options.defaultAdsStorageConsentState
+          }
+          if(self.options.defaultAnalyticsStorageConsentState && self.options.defaultAnalyticsStorageConsentState!=UNSPECIFIED){
+            consent.analytics_storage = self.options.defaultAnalyticsStorageConsentState
+          }
+          if(self.options.waitTimeToUpdateConsentStage && self.options.waitTimeToUpdateConsentStage>0){
+            consent.wait_for_update = self.options.waitTimeToUpdateConsentStage
+          }
+          window.gtag('consent', 'default', consent)
+     } 
+
     self.ready();
   });
 };
diff --git a/integrations/google-adwords-new/test/index.test.js b/integrations/google-adwords-new/test/index.test.js
index eccb7ecb1..c172b25b5 100644
--- a/integrations/google-adwords-new/test/index.test.js
+++ b/integrations/google-adwords-new/test/index.test.js
@@ -66,7 +66,10 @@ describe('Google AdWords New', function() {
         }
       }
     ],
-    defaultPageConversion: 'qnCxCOvxq18Q1ta71QM'
+    defaultPageConversion: 'qnCxCOvxq18Q1ta71QM',
+    adUserDataConsentState :'granted',
+    adPersonalizationConsentState: 'denied',
+    waitTimeToUpdateConsentStage:1000
   };
 
   beforeEach(function() {
@@ -95,6 +98,12 @@ describe('Google AdWords New', function() {
         .option('pageLoadConversions', {})
         .option('defaultPageConversion', '')
         .option('disableAdPersonalization', false)
+        .option('enableConsentMode',false)
+        .option('adUserDataConsentState')
+        .option('adPersonalizationConsentState')
+        .option('defaultAdsStorageConsentState')
+        .option('defaultAnalyticsStorageConsentState')
+        .option('waitTimeToUpdateConsentStage')
         .tag(
           '<script src="https://www.googletagmanager.com/gtag/js?id={{ accountId }}">'
         )
@@ -115,13 +124,14 @@ describe('Google AdWords New', function() {
   });
 
   describe('loading', function() {
-    it('should load', function(done) {
-      analytics.load(googleadwordsnew, done);
-    });
+    // it('should load', function(done) {
+    //   analytics.load(googleadwordsnew, done);
+    // });
 
     it('should disable ad personalization before `config` statements when settings enabled', function(done) {
       googleadwordsnew.options.disableAdPersonalization = true;
       analytics.once('ready', function() {
+        console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>',window.gtag.args);
         analytics.deepEqual(window.gtag.args[1], [
           'set',
           'allow_ad_personalization_signals',
@@ -162,6 +172,46 @@ describe('Google AdWords New', function() {
       analytics.initialize();
       analytics.spy(window, 'gtag');
     });
+
+    it('should add consent signals only if enableConsentMode is set to true', function(done) {
+      googleadwordsnew.options.enableConsentMode = true;
+      analytics.once('ready', function() {
+        analytics.deepEqual(window.gtag.args[2], [
+          'consent',
+          'default',
+          {
+            wait_for_update: 1000,
+            ad_user_data: 'granted',
+            ad_personalization:'denied'
+          }
+        ]);
+        done();
+      });
+      analytics.initialize();
+      analytics.spy(window, 'gtag');
+    });
+
+
+    it('should skip adding those consent signal those are unspecified or null', function(done) {
+      googleadwordsnew.options.enableConsentMode = true;
+      googleadwordsnew.options.adPersonalizationConsentState = 'unspecified';
+      googleadwordsnew.options.defaultAnalyticsStorageConsentState='denied';
+      analytics.once('ready', function() {
+        analytics.deepEqual(window.gtag.args[2], [
+          'consent',
+          'default',
+          {
+            wait_for_update: 1000,
+            ad_user_data: 'granted',
+            analytics_storage:'denied'
+    
+          }
+        ]);
+        done();
+      });
+      analytics.initialize();
+      analytics.spy(window, 'gtag');
+    });
   });
 
   describe('after loading', function() {

From 447ee6a4f72588e425cb95f3339559c850794f84 Mon Sep 17 00:00:00 2001
From: Gaurav Kochar <gaurav.kochar@segment.com>
Date: Tue, 27 Feb 2024 16:34:00 +0530
Subject: [PATCH 2/4] conflicts resolved

---
 integrations/google-adwords-new/lib/index.js       | 12 ++++++------
 integrations/google-adwords-new/test/index.test.js | 11 +++++------
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/integrations/google-adwords-new/lib/index.js b/integrations/google-adwords-new/lib/index.js
index 651aa12db..863b64b13 100644
--- a/integrations/google-adwords-new/lib/index.js
+++ b/integrations/google-adwords-new/lib/index.js
@@ -25,11 +25,11 @@ var GoogleAdWordsNew = (module.exports = integration('Google AdWords New')
   .option('disableAdPersonalization', false)
   .option('floodlightAccountId', '')
   .option('enableConsentMode',false)
-  .option('adUserDataConsentState')
-  .option('adPersonalizationConsentState')
-  .option('defaultAdsStorageConsentState')
-  .option('defaultAnalyticsStorageConsentState')
-  .option('waitTimeToUpdateConsentStage')
+  .option('adUserDataConsentState',null)
+  .option('adPersonalizationConsentState',null)
+  .option('defaultAdsStorageConsentState',null)
+  .option('defaultAnalyticsStorageConsentState',null)
+  .option('waitTimeToUpdateConsentStage',0)
   // The ID in this line (i.e. the gtag.js ID) does not determine which account(s) will receive data from the tag; rather, it is used to uniquely identify your global site tag. Which account(s) receive data from the tag is determined by calling the config command (and by using the send_to parameter on an event). For instance, if you use Google Analytics, you may already have the gtag.js global site tag installed on your site. In that case, the gtag.js ID may be that of the Google Analytics property where you first obtained the snippet.
   .tag(
     '<script src="https://www.googletagmanager.com/gtag/js?id={{ accountId }}">'
@@ -66,7 +66,7 @@ GoogleAdWordsNew.prototype.initialize = function() {
     if (self.options.floodlightAccountId) {
       window.gtag('config', self.options.floodlightAccountId, config);
     }
-    window.gtag('config', self.options.accountId, config);
+      window.gtag('config', self.options.accountId, config);
 
     if (self.options.enableConsentMode) {
      let consent={};
diff --git a/integrations/google-adwords-new/test/index.test.js b/integrations/google-adwords-new/test/index.test.js
index c172b25b5..08807c982 100644
--- a/integrations/google-adwords-new/test/index.test.js
+++ b/integrations/google-adwords-new/test/index.test.js
@@ -99,11 +99,11 @@ describe('Google AdWords New', function() {
         .option('defaultPageConversion', '')
         .option('disableAdPersonalization', false)
         .option('enableConsentMode',false)
-        .option('adUserDataConsentState')
-        .option('adPersonalizationConsentState')
-        .option('defaultAdsStorageConsentState')
-        .option('defaultAnalyticsStorageConsentState')
-        .option('waitTimeToUpdateConsentStage')
+        .option('adUserDataConsentState',null)
+        .option('adPersonalizationConsentState',null)
+        .option('defaultAdsStorageConsentState',null)
+        .option('defaultAnalyticsStorageConsentState',null)
+        .option('waitTimeToUpdateConsentStage',0)
         .tag(
           '<script src="https://www.googletagmanager.com/gtag/js?id={{ accountId }}">'
         )
@@ -131,7 +131,6 @@ describe('Google AdWords New', function() {
     it('should disable ad personalization before `config` statements when settings enabled', function(done) {
       googleadwordsnew.options.disableAdPersonalization = true;
       analytics.once('ready', function() {
-        console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>',window.gtag.args);
         analytics.deepEqual(window.gtag.args[1], [
           'set',
           'allow_ad_personalization_signals',

From 83d31ed5db5771f4e20d521b5f6a2d9eca575980 Mon Sep 17 00:00:00 2001
From: Gaurav Kochar <gaurav.kochar@segment.com>
Date: Wed, 28 Feb 2024 19:35:59 +0530
Subject: [PATCH 3/4] worked on adding consent signal to Google Tag

---
 integrations/google-adwords-new/lib/index.js       |  6 +++---
 integrations/google-adwords-new/test/index.test.js | 10 +++++-----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/integrations/google-adwords-new/lib/index.js b/integrations/google-adwords-new/lib/index.js
index 863b64b13..4c1a5a8e9 100644
--- a/integrations/google-adwords-new/lib/index.js
+++ b/integrations/google-adwords-new/lib/index.js
@@ -29,7 +29,7 @@ var GoogleAdWordsNew = (module.exports = integration('Google AdWords New')
   .option('adPersonalizationConsentState',null)
   .option('defaultAdsStorageConsentState',null)
   .option('defaultAnalyticsStorageConsentState',null)
-  .option('waitTimeToUpdateConsentStage',0)
+  .option('waitTimeToUpdateConsentState',0)
   // The ID in this line (i.e. the gtag.js ID) does not determine which account(s) will receive data from the tag; rather, it is used to uniquely identify your global site tag. Which account(s) receive data from the tag is determined by calling the config command (and by using the send_to parameter on an event). For instance, if you use Google Analytics, you may already have the gtag.js global site tag installed on your site. In that case, the gtag.js ID may be that of the Google Analytics property where you first obtained the snippet.
   .tag(
     '<script src="https://www.googletagmanager.com/gtag/js?id={{ accountId }}">'
@@ -82,8 +82,8 @@ GoogleAdWordsNew.prototype.initialize = function() {
           if(self.options.defaultAnalyticsStorageConsentState && self.options.defaultAnalyticsStorageConsentState!=UNSPECIFIED){
             consent.analytics_storage = self.options.defaultAnalyticsStorageConsentState
           }
-          if(self.options.waitTimeToUpdateConsentStage && self.options.waitTimeToUpdateConsentStage>0){
-            consent.wait_for_update = self.options.waitTimeToUpdateConsentStage
+          if(self.options.waitTimeToUpdateConsentState && self.options.waitTimeToUpdateConsentState>0){
+            consent.wait_for_update = self.options.waitTimeToUpdateConsentState
           }
           window.gtag('consent', 'default', consent)
      } 
diff --git a/integrations/google-adwords-new/test/index.test.js b/integrations/google-adwords-new/test/index.test.js
index 08807c982..4d23c57d6 100644
--- a/integrations/google-adwords-new/test/index.test.js
+++ b/integrations/google-adwords-new/test/index.test.js
@@ -69,7 +69,7 @@ describe('Google AdWords New', function() {
     defaultPageConversion: 'qnCxCOvxq18Q1ta71QM',
     adUserDataConsentState :'granted',
     adPersonalizationConsentState: 'denied',
-    waitTimeToUpdateConsentStage:1000
+    waitTimeToUpdateConsentState:1000
   };
 
   beforeEach(function() {
@@ -103,7 +103,7 @@ describe('Google AdWords New', function() {
         .option('adPersonalizationConsentState',null)
         .option('defaultAdsStorageConsentState',null)
         .option('defaultAnalyticsStorageConsentState',null)
-        .option('waitTimeToUpdateConsentStage',0)
+        .option('waitTimeToUpdateConsentState',0)
         .tag(
           '<script src="https://www.googletagmanager.com/gtag/js?id={{ accountId }}">'
         )
@@ -124,9 +124,9 @@ describe('Google AdWords New', function() {
   });
 
   describe('loading', function() {
-    // it('should load', function(done) {
-    //   analytics.load(googleadwordsnew, done);
-    // });
+    it('should load', function(done) {
+      analytics.load(googleadwordsnew, done);
+    });
 
     it('should disable ad personalization before `config` statements when settings enabled', function(done) {
       googleadwordsnew.options.disableAdPersonalization = true;

From e0dfc8aaf0986c11b61f487ffa6c366b3e1027e0 Mon Sep 17 00:00:00 2001
From: Gaurav Kochar <gaurav.kochar@segment.com>
Date: Mon, 4 Mar 2024 16:58:50 +0530
Subject: [PATCH 4/4] Fixed issue of Shareasale not working without use total
 as amount enabled

---
 integrations/shareasale/lib/index.js       |  5 +++--
 integrations/shareasale/test/index.test.js | 10 +++++-----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/integrations/shareasale/lib/index.js b/integrations/shareasale/lib/index.js
index 89d017c00..fea505a29 100644
--- a/integrations/shareasale/lib/index.js
+++ b/integrations/shareasale/lib/index.js
@@ -36,10 +36,11 @@ ShareASale.prototype.orderCompleted = function(track) {
   var orderId = track.orderId();
   var isRepeat = track.proxy('properties.repeat');
   var subtotal = (track.subtotal() || 0).toFixed(2);
+  var total= (track.total() || 0).toFixed(2)
   var orderTotal =
     this.options.useTotalAsAmount && track.total()
-      ? track.total().toFixed(2)
-      : subtotal.toFixed(2);
+      ? total
+      : subtotal;
   var products = track.products();
   var currency = track.currency() || this.options.currency;
   var coupon = track.coupon() || '';
diff --git a/integrations/shareasale/test/index.test.js b/integrations/shareasale/test/index.test.js
index e8397ba0a..a9aa7d823 100644
--- a/integrations/shareasale/test/index.test.js
+++ b/integrations/shareasale/test/index.test.js
@@ -69,11 +69,11 @@ describe('ShareASale', function() {
           subtotal: 42,
           shipping: 10,
           tax: 3.5,
-          total: 55.5,
+          total: 55,
           revenue: 15
         });
         analytics.loaded(
-          '<img src="https://shareasale.com/sale.cfm?amount=55.50&tracking=123&transtype=sale&merchantID=bonobos&skulist=&quantitylist=&pricelist=&currency=USD&couponcode=">'
+          '<img src="https://shareasale.com/sale.cfm?amount=55.00&tracking=123&transtype=sale&merchantID=bonobos&skulist=&quantitylist=&pricelist=&currency=USD&couponcode=">'
         );
       });
 
@@ -93,10 +93,10 @@ describe('ShareASale', function() {
           orderId: 123,
           shipping: 10,
           tax: 3.5,
-          total: 55.5
+          total: 55
         });
         analytics.loaded(
-          '<img src="https://shareasale.com/sale.cfm?amount=42.00&tracking=123&transtype=sale&merchantID=bonobos&skulist=&quantitylist=&pricelist=&currency=USD&couponcode=">'
+          '<img src="https://shareasale.com/sale.cfm?amount=41.50&tracking=123&transtype=sale&merchantID=bonobos&skulist=&quantitylist=&pricelist=&currency=USD&couponcode=">'
         );
       });
 
@@ -148,7 +148,7 @@ describe('ShareASale', function() {
           total: 55.5
         });
         analytics.loaded(
-          '<img src="https://shareasale.com/sale.cfm?amount=42.00&tracking=123&transtype=sale&merchantID=bonobos&skulist=&quantitylist=&pricelist=&currency=USD&couponcode=">'
+          '<img src="https://shareasale.com/sale.cfm?amount=47.00&tracking=123&transtype=sale&merchantID=bonobos&skulist=&quantitylist=&pricelist=&currency=USD&couponcode=">'
         );
       });