Skip to content

Commit 171ac62

Browse files
committed
[CST-6753] Maintain compatibility with version 3
1 parent f3f89b3 commit 171ac62

File tree

4 files changed

+117
-38
lines changed

4 files changed

+117
-38
lines changed

src/app/statistics/google-analytics.service.spec.ts

Lines changed: 68 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Angulartics2GoogleTagManager } from 'angulartics2';
1+
import { Angulartics2GoogleAnalytics, Angulartics2GoogleTagManager } from 'angulartics2';
22
import { of } from 'rxjs';
33

44
import { GoogleAnalyticsService } from './google-analytics.service';
@@ -10,11 +10,13 @@ import { GOOGLE_ANALYTICS_KLARO_KEY } from '../shared/cookies/klaro-configuratio
1010

1111
describe('GoogleAnalyticsService', () => {
1212
const trackingIdProp = 'google.analytics.key';
13-
const trackingIdTestValue = 'mock-tracking-id';
13+
const trackingIdV4TestValue = 'G-mock-tracking-id';
14+
const trackingIdV3TestValue = 'UA-mock-tracking-id';
1415
const innerHTMLTestValue = 'mock-script-inner-html';
1516
const srcTestValue = 'mock-script-src';
1617
let service: GoogleAnalyticsService;
17-
let angularticsSpy: Angulartics2GoogleTagManager;
18+
let googleAnalyticsSpy: Angulartics2GoogleAnalytics;
19+
let googleTagManagerSpy: Angulartics2GoogleTagManager;
1820
let configSpy: ConfigurationDataService;
1921
let klaroServiceSpy: jasmine.SpyObj<KlaroService>;
2022
let scriptElementMock: any;
@@ -32,15 +34,18 @@ describe('GoogleAnalyticsService', () => {
3234
});
3335

3436
beforeEach(() => {
35-
angularticsSpy = jasmine.createSpyObj('Angulartics2GoogleTagManager', [
37+
googleAnalyticsSpy = jasmine.createSpyObj('Angulartics2GoogleAnalytics', [
38+
'startTracking',
39+
]);
40+
googleTagManagerSpy = jasmine.createSpyObj('Angulartics2GoogleTagManager', [
3641
'startTracking',
3742
]);
3843

3944
klaroServiceSpy = jasmine.createSpyObj('KlaroService', {
4045
'getSavedPreferences': jasmine.createSpy('getSavedPreferences')
4146
});
4247

43-
configSpy = createConfigSuccessSpy(trackingIdTestValue);
48+
configSpy = createConfigSuccessSpy(trackingIdV4TestValue);
4449

4550
scriptElementMock = {
4651
set src(newVal) { /* noop */ },
@@ -66,7 +71,7 @@ describe('GoogleAnalyticsService', () => {
6671
GOOGLE_ANALYTICS_KLARO_KEY: true
6772
}));
6873

69-
service = new GoogleAnalyticsService(angularticsSpy, klaroServiceSpy, configSpy, documentSpy );
74+
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy );
7075
});
7176

7277
it('should be created', () => {
@@ -90,7 +95,7 @@ describe('GoogleAnalyticsService', () => {
9095
GOOGLE_ANALYTICS_KLARO_KEY: true
9196
}));
9297

93-
service = new GoogleAnalyticsService(angularticsSpy, klaroServiceSpy, configSpy, documentSpy);
98+
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
9499
});
95100

96101
it('should NOT add a script to the body', () => {
@@ -100,7 +105,8 @@ describe('GoogleAnalyticsService', () => {
100105

101106
it('should NOT start tracking', () => {
102107
service.addTrackingIdToPage();
103-
expect(angularticsSpy.startTracking).toHaveBeenCalledTimes(0);
108+
expect(googleAnalyticsSpy.startTracking).toHaveBeenCalledTimes(0);
109+
expect(googleTagManagerSpy.startTracking).toHaveBeenCalledTimes(0);
104110
});
105111
});
106112

@@ -111,7 +117,7 @@ describe('GoogleAnalyticsService', () => {
111117
klaroServiceSpy.getSavedPreferences.and.returnValue(of({
112118
[GOOGLE_ANALYTICS_KLARO_KEY]: true
113119
}));
114-
service = new GoogleAnalyticsService(angularticsSpy, klaroServiceSpy, configSpy, documentSpy);
120+
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
115121
});
116122

117123
it('should NOT add a script to the body', () => {
@@ -121,15 +127,16 @@ describe('GoogleAnalyticsService', () => {
121127

122128
it('should NOT start tracking', () => {
123129
service.addTrackingIdToPage();
124-
expect(angularticsSpy.startTracking).toHaveBeenCalledTimes(0);
130+
expect(googleAnalyticsSpy.startTracking).toHaveBeenCalledTimes(0);
131+
expect(googleTagManagerSpy.startTracking).toHaveBeenCalledTimes(0);
125132
});
126133
});
127134

128135
describe('when google-analytics cookie preferences are not existing', () => {
129136
beforeEach(() => {
130-
configSpy = createConfigSuccessSpy(trackingIdTestValue);
137+
configSpy = createConfigSuccessSpy(trackingIdV4TestValue);
131138
klaroServiceSpy.getSavedPreferences.and.returnValue(of({}));
132-
service = new GoogleAnalyticsService(angularticsSpy, klaroServiceSpy, configSpy, documentSpy);
139+
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
133140
});
134141

135142
it('should NOT add a script to the body', () => {
@@ -139,18 +146,19 @@ describe('GoogleAnalyticsService', () => {
139146

140147
it('should NOT start tracking', () => {
141148
service.addTrackingIdToPage();
142-
expect(angularticsSpy.startTracking).toHaveBeenCalledTimes(0);
149+
expect(googleAnalyticsSpy.startTracking).toHaveBeenCalledTimes(0);
150+
expect(googleTagManagerSpy.startTracking).toHaveBeenCalledTimes(0);
143151
});
144152
});
145153

146154

147155
describe('when google-analytics cookie preferences are set to false', () => {
148156
beforeEach(() => {
149-
configSpy = createConfigSuccessSpy(trackingIdTestValue);
157+
configSpy = createConfigSuccessSpy(trackingIdV4TestValue);
150158
klaroServiceSpy.getSavedPreferences.and.returnValue(of({
151159
[GOOGLE_ANALYTICS_KLARO_KEY]: false
152160
}));
153-
service = new GoogleAnalyticsService(angularticsSpy, klaroServiceSpy, configSpy, documentSpy);
161+
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
154162
});
155163

156164
it('should NOT add a script to the body', () => {
@@ -160,18 +168,19 @@ describe('GoogleAnalyticsService', () => {
160168

161169
it('should NOT start tracking', () => {
162170
service.addTrackingIdToPage();
163-
expect(angularticsSpy.startTracking).toHaveBeenCalledTimes(0);
171+
expect(googleAnalyticsSpy.startTracking).toHaveBeenCalledTimes(0);
172+
expect(googleTagManagerSpy.startTracking).toHaveBeenCalledTimes(0);
164173
});
165174
});
166175

167-
describe('when both google-analytics cookie and the tracking id are non-empty', () => {
176+
describe('when both google-analytics cookie and the tracking v4 id are non-empty', () => {
168177

169178
beforeEach(() => {
170-
configSpy = createConfigSuccessSpy(trackingIdTestValue);
179+
configSpy = createConfigSuccessSpy(trackingIdV4TestValue);
171180
klaroServiceSpy.getSavedPreferences.and.returnValue(of({
172181
[GOOGLE_ANALYTICS_KLARO_KEY]: true
173182
}));
174-
service = new GoogleAnalyticsService(angularticsSpy, klaroServiceSpy, configSpy, documentSpy);
183+
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
175184
});
176185

177186
it('should create a script tag whose innerHTML contains the tracking id', () => {
@@ -183,10 +192,10 @@ describe('GoogleAnalyticsService', () => {
183192
expect(documentSpy.createElement('script')).toBe(scriptElementMock);
184193

185194
expect(srcSpy).toHaveBeenCalledTimes(1);
186-
expect(srcSpy.calls.argsFor(0)[0]).toContain(trackingIdTestValue);
195+
expect(srcSpy.calls.argsFor(0)[0]).toContain(trackingIdV4TestValue);
187196

188197
expect(innerHTMLSpy).toHaveBeenCalledTimes(1);
189-
expect(innerHTMLSpy.calls.argsFor(0)[0]).toContain(trackingIdTestValue);
198+
expect(innerHTMLSpy.calls.argsFor(0)[0]).toContain(trackingIdV4TestValue);
190199
});
191200

192201
it('should add a script to the body', () => {
@@ -196,9 +205,46 @@ describe('GoogleAnalyticsService', () => {
196205

197206
it('should start tracking', () => {
198207
service.addTrackingIdToPage();
199-
expect(angularticsSpy.startTracking).toHaveBeenCalledTimes(1);
208+
expect(googleAnalyticsSpy.startTracking).not.toHaveBeenCalled();
209+
expect(googleTagManagerSpy.startTracking).toHaveBeenCalledTimes(1);
210+
});
211+
});
212+
213+
describe('when both google-analytics cookie and the tracking id v3 are non-empty', () => {
214+
215+
beforeEach(() => {
216+
configSpy = createConfigSuccessSpy(trackingIdV3TestValue);
217+
klaroServiceSpy.getSavedPreferences.and.returnValue(of({
218+
[GOOGLE_ANALYTICS_KLARO_KEY]: true
219+
}));
220+
service = new GoogleAnalyticsService(googleAnalyticsSpy, googleTagManagerSpy, klaroServiceSpy, configSpy, documentSpy);
221+
});
222+
223+
it('should create a script tag whose innerHTML contains the tracking id', () => {
224+
service.addTrackingIdToPage();
225+
expect(documentSpy.createElement).toHaveBeenCalledTimes(1);
226+
expect(documentSpy.createElement).toHaveBeenCalledWith('script');
227+
228+
// sanity check
229+
expect(documentSpy.createElement('script')).toBe(scriptElementMock);
230+
231+
expect(innerHTMLSpy).toHaveBeenCalledTimes(1);
232+
expect(innerHTMLSpy.calls.argsFor(0)[0]).toContain(trackingIdV3TestValue);
233+
});
234+
235+
it('should add a script to the body', () => {
236+
service.addTrackingIdToPage();
237+
expect(bodyElementSpy.appendChild).toHaveBeenCalledTimes(1);
238+
});
239+
240+
it('should start tracking', () => {
241+
service.addTrackingIdToPage();
242+
expect(googleAnalyticsSpy.startTracking).toHaveBeenCalledTimes(1);
243+
expect(googleTagManagerSpy.startTracking).not.toHaveBeenCalled();
200244
});
201245
});
246+
202247
});
248+
203249
});
204250
});

src/app/statistics/google-analytics.service.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { DOCUMENT } from '@angular/common';
22
import { Inject, Injectable } from '@angular/core';
33

4-
import { Angulartics2GoogleTagManager } from 'angulartics2';
4+
import { Angulartics2GoogleAnalytics, Angulartics2GoogleTagManager } from 'angulartics2';
55
import { combineLatest } from 'rxjs';
66

77
import { ConfigurationDataService } from '../core/data/configuration-data.service';
@@ -18,8 +18,8 @@ import { GOOGLE_ANALYTICS_KLARO_KEY } from '../shared/cookies/klaro-configuratio
1818
export class GoogleAnalyticsService {
1919

2020
constructor(
21-
// private angulartics: Angulartics2GoogleAnalytics,
22-
private angulartics: Angulartics2GoogleTagManager,
21+
private googleAnalytics: Angulartics2GoogleAnalytics,
22+
private googleTagManager: Angulartics2GoogleTagManager,
2323
private klaroService: KlaroService,
2424
private configService: ConfigurationDataService,
2525
@Inject(DOCUMENT) private document: any,
@@ -36,7 +36,9 @@ export class GoogleAnalyticsService {
3636
const googleKey$ = this.configService.findByPropertyName('google.analytics.key').pipe(
3737
getFirstCompletedRemoteData(),
3838
);
39-
combineLatest([this.klaroService.getSavedPreferences(), googleKey$])
39+
const preferences$ = this.klaroService.getSavedPreferences();
40+
41+
combineLatest([preferences$, googleKey$])
4042
.subscribe(([preferences, remoteData]) => {
4143
// make sure user has accepted Google Analytics consents
4244
if (isEmpty(preferences) || isEmpty(preferences[GOOGLE_ANALYTICS_KLARO_KEY]) || !preferences[GOOGLE_ANALYTICS_KLARO_KEY]) {
@@ -55,18 +57,37 @@ export class GoogleAnalyticsService {
5557
return;
5658
}
5759

58-
// add GTag snippet to page
59-
const keyScript = this.document.createElement('script');
60-
keyScript.src = `https://www.googletagmanager.com/gtag/js?id=${trackingId}`;
61-
this.document.body.appendChild(keyScript);
60+
if (this.isGTagVersion(trackingId)) {
61+
62+
// add GTag snippet to page
63+
const keyScript = this.document.createElement('script');
64+
keyScript.src = `https://www.googletagmanager.com/gtag/js?id=${trackingId}`;
65+
this.document.body.appendChild(keyScript);
6266

63-
const libScript = this.document.createElement('script');
64-
libScript.innerHTML = `window.dataLayer = window.dataLayer || [];function gtag(){window.dataLayer.push(arguments);}
67+
const libScript = this.document.createElement('script');
68+
libScript.innerHTML = `window.dataLayer = window.dataLayer || [];function gtag(){window.dataLayer.push(arguments);}
6569
gtag('js', new Date());gtag('config', '${trackingId}');`;
66-
this.document.body.appendChild(libScript);
70+
this.document.body.appendChild(libScript);
71+
72+
// start tracking
73+
this.googleTagManager.startTracking();
74+
} else {
75+
// add trackingId snippet to page
76+
const keyScript = this.document.createElement('script');
77+
keyScript.innerHTML = `(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
78+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
79+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
80+
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
81+
ga('create', '${trackingId}', 'auto');`;
82+
this.document.body.appendChild(keyScript);
6783

68-
// start tracking
69-
this.angulartics.startTracking();
84+
// start tracking
85+
this.googleAnalytics.startTracking();
86+
}
7087
});
7188
}
89+
90+
private isGTagVersion(trackingId: string) {
91+
return trackingId && trackingId.startsWith('G-');
92+
}
7293
}

src/modules/app/browser-app.module.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@ import { AppModule } from '../../app/app.module';
1515
import { ClientCookieService } from '../../app/core/services/client-cookie.service';
1616
import { CookieService } from '../../app/core/services/cookie.service';
1717
import { AuthService } from '../../app/core/auth/auth.service';
18-
import { Angulartics2RouterlessModule } from 'angulartics2';
18+
import { Angulartics2GoogleTagManager, Angulartics2RouterlessModule } from 'angulartics2';
1919
import { SubmissionService } from '../../app/submission/submission.service';
2020
import { StatisticsModule } from '../../app/statistics/statistics.module';
2121
import { BrowserKlaroService } from '../../app/shared/cookies/browser-klaro.service';
2222
import { KlaroService } from '../../app/shared/cookies/klaro.service';
2323
import { HardRedirectService } from '../../app/core/services/hard-redirect.service';
24-
import { BrowserHardRedirectService, locationProvider, LocationToken } from '../../app/core/services/browser-hard-redirect.service';
24+
import {
25+
BrowserHardRedirectService,
26+
locationProvider,
27+
LocationToken
28+
} from '../../app/core/services/browser-hard-redirect.service';
2529
import { LocaleService } from '../../app/core/locale/locale.service';
2630
import { GoogleAnalyticsService } from '../../app/statistics/google-analytics.service';
2731
import { AuthRequestService } from '../../app/core/auth/auth-request.service';
@@ -95,6 +99,10 @@ export function getRequest(transferState: TransferState): any {
9599
provide: GoogleAnalyticsService,
96100
useClass: GoogleAnalyticsService,
97101
},
102+
{
103+
provide: Angulartics2GoogleTagManager,
104+
useClass: Angulartics2GoogleTagManager
105+
},
98106
{
99107
provide: AuthRequestService,
100108
useClass: BrowserAuthRequestService,

src/modules/app/server-app.module.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { ServerModule, ServerTransferStateModule } from '@angular/platform-serve
66

77
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
88

9-
import { Angulartics2, Angulartics2GoogleTagManager } from 'angulartics2';
9+
import { Angulartics2, Angulartics2GoogleAnalytics, Angulartics2GoogleTagManager } from 'angulartics2';
1010

1111
import { AppComponent } from '../../app/app.component';
1212

@@ -58,6 +58,10 @@ export function createTranslateLoader(transferState: TransferState) {
5858
provide: Angulartics2,
5959
useClass: Angulartics2Mock
6060
},
61+
{
62+
provide: Angulartics2GoogleAnalytics,
63+
useClass: AngularticsProviderMock
64+
},
6165
{
6266
provide: Angulartics2GoogleTagManager,
6367
useClass: AngularticsProviderMock

0 commit comments

Comments
 (0)