Skip to content

Commit 1370363

Browse files
authored
Merge pull request #1826 from 4Science/CST-6753_GA4
Update Google Analytics to version 4
2 parents 6fa9eb8 + 171ac62 commit 1370363

11 files changed

+291
-62
lines changed

src/app/app.component.spec.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { Store, StoreModule } from '@ngrx/store';
22
import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing';
33
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
4-
import { CommonModule, DOCUMENT } from '@angular/common';
4+
import { CommonModule } from '@angular/common';
55
import { ActivatedRoute, Router } from '@angular/router';
66
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
7-
import { Angulartics2GoogleAnalytics } from 'angulartics2';
87

98
// Load the implementations that should be tested
109
import { AppComponent } from './app.component';
@@ -73,7 +72,6 @@ describe('App component', () => {
7372
providers: [
7473
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
7574
{ provide: MetadataService, useValue: new MetadataServiceMock() },
76-
{ provide: Angulartics2GoogleAnalytics, useValue: new AngularticsProviderMock() },
7775
{ provide: Angulartics2DSpace, useValue: new AngularticsProviderMock() },
7876
{ provide: AuthService, useValue: new AuthServiceMock() },
7977
{ provide: Router, useValue: new RouterMock() },

src/app/root/root.component.spec.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { TranslateLoaderMock } from '../shared/mocks/translate-loader.mock';
99
import { NativeWindowRef, NativeWindowService } from '../core/services/window.service';
1010
import { MetadataService } from '../core/metadata/metadata.service';
1111
import { MetadataServiceMock } from '../shared/mocks/metadata-service.mock';
12-
import { Angulartics2GoogleAnalytics } from 'angulartics2';
1312
import { AngularticsProviderMock } from '../shared/mocks/angulartics-provider.service.mock';
1413
import { Angulartics2DSpace } from '../statistics/angulartics/dspace-provider';
1514
import { AuthService } from '../core/auth/auth.service';
@@ -50,7 +49,6 @@ describe('RootComponent', () => {
5049
providers: [
5150
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
5251
{ provide: MetadataService, useValue: new MetadataServiceMock() },
53-
{ provide: Angulartics2GoogleAnalytics, useValue: new AngularticsProviderMock() },
5452
{ provide: Angulartics2DSpace, useValue: new AngularticsProviderMock() },
5553
{ provide: AuthService, useValue: new AuthServiceMock() },
5654
{ provide: Router, useValue: new RouterMock() },

src/app/root/root.component.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { Router } from '@angular/router';
55
import { combineLatest as combineLatestObservable, Observable, of } from 'rxjs';
66
import { Store } from '@ngrx/store';
77
import { TranslateService } from '@ngx-translate/core';
8-
import { Angulartics2GoogleAnalytics } from 'angulartics2';
98

109
import { MetadataService } from '../core/metadata/metadata.service';
1110
import { HostWindowState } from '../shared/search/host-window.reducer';
@@ -51,7 +50,6 @@ export class RootComponent implements OnInit {
5150
private translate: TranslateService,
5251
private store: Store<HostWindowState>,
5352
private metadata: MetadataService,
54-
private angulartics2GoogleAnalytics: Angulartics2GoogleAnalytics,
5553
private angulartics2DSpace: Angulartics2DSpace,
5654
private authService: AuthService,
5755
private router: Router,

src/app/shared/cookies/browser-klaro.service.spec.ts

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ import { AuthService } from '../../core/auth/auth.service';
1010
import { CookieService } from '../../core/services/cookie.service';
1111
import { getTestScheduler } from 'jasmine-marbles';
1212
import { MetadataValue } from '../../core/shared/metadata.models';
13-
import {clone, cloneDeep} from 'lodash';
13+
import { clone, cloneDeep } from 'lodash';
1414
import { ConfigurationDataService } from '../../core/data/configuration-data.service';
15-
import {createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$} from '../remote-data.utils';
15+
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../remote-data.utils';
1616
import { ConfigurationProperty } from '../../core/shared/configuration-property.model';
17+
import { ANONYMOUS_STORAGE_NAME_KLARO } from './klaro-configuration';
18+
import { TestScheduler } from 'rxjs/testing';
1719

1820
describe('BrowserKlaroService', () => {
1921
const trackingIdProp = 'google.analytics.key';
@@ -29,7 +31,7 @@ describe('BrowserKlaroService', () => {
2931
let configurationDataService: ConfigurationDataService;
3032
const createConfigSuccessSpy = (...values: string[]) => jasmine.createSpyObj('configurationDataService', {
3133
findByPropertyName: createSuccessfulRemoteDataObject$({
32-
... new ConfigurationProperty(),
34+
...new ConfigurationProperty(),
3335
name: trackingIdProp,
3436
values: values,
3537
}),
@@ -42,7 +44,9 @@ describe('BrowserKlaroService', () => {
4244
let findByPropertyName;
4345

4446
beforeEach(() => {
45-
user = new EPerson();
47+
user = Object.assign(new EPerson(), {
48+
uuid: 'test-user'
49+
});
4650

4751
translateService = getMockTranslateService();
4852
ePersonService = jasmine.createSpyObj('ePersonService', {
@@ -104,7 +108,7 @@ describe('BrowserKlaroService', () => {
104108
services: [{
105109
name: appName,
106110
purposes: [purpose]
107-
},{
111+
}, {
108112
name: googleAnalytics,
109113
purposes: [purpose]
110114
}],
@@ -219,6 +223,40 @@ describe('BrowserKlaroService', () => {
219223
});
220224
});
221225

226+
describe('getSavedPreferences', () => {
227+
let scheduler: TestScheduler;
228+
beforeEach(() => {
229+
scheduler = getTestScheduler();
230+
});
231+
232+
describe('when no user is autheticated', () => {
233+
beforeEach(() => {
234+
spyOn(service as any, 'getUser$').and.returnValue(observableOf(undefined));
235+
});
236+
237+
it('should return the cookie consents object', () => {
238+
scheduler.schedule(() => service.getSavedPreferences().subscribe());
239+
scheduler.flush();
240+
241+
expect(cookieService.get).toHaveBeenCalledWith(ANONYMOUS_STORAGE_NAME_KLARO);
242+
});
243+
});
244+
245+
describe('when user is autheticated', () => {
246+
beforeEach(() => {
247+
spyOn(service as any, 'getUser$').and.returnValue(observableOf(user));
248+
});
249+
250+
it('should return the cookie consents object', () => {
251+
scheduler.schedule(() => service.getSavedPreferences().subscribe());
252+
scheduler.flush();
253+
254+
expect(cookieService.get).toHaveBeenCalledWith('klaro-' + user.uuid);
255+
});
256+
});
257+
});
258+
259+
222260
describe('setSettingsForUser when there are changes', () => {
223261
const cookieConsent = { test: 'testt' };
224262
const cookieConsentString = '{test: \'testt\'}';
@@ -271,40 +309,40 @@ describe('BrowserKlaroService', () => {
271309
});
272310
it('should not filter googleAnalytics when servicesToHide are empty', () => {
273311
const filteredConfig = (service as any).filterConfigServices([]);
274-
expect(filteredConfig).toContain(jasmine.objectContaining({name: googleAnalytics}));
312+
expect(filteredConfig).toContain(jasmine.objectContaining({ name: googleAnalytics }));
275313
});
276314
it('should filter services using names passed as servicesToHide', () => {
277315
const filteredConfig = (service as any).filterConfigServices([googleAnalytics]);
278-
expect(filteredConfig).not.toContain(jasmine.objectContaining({name: googleAnalytics}));
316+
expect(filteredConfig).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
279317
});
280318
it('should have been initialized with googleAnalytics', () => {
281319
service.initialize();
282-
expect(service.klaroConfig.services).toContain(jasmine.objectContaining({name: googleAnalytics}));
320+
expect(service.klaroConfig.services).toContain(jasmine.objectContaining({ name: googleAnalytics }));
283321
});
284322
it('should filter googleAnalytics when empty configuration is retrieved', () => {
285323
configurationDataService.findByPropertyName = jasmine.createSpy().withArgs(GOOGLE_ANALYTICS_KEY).and.returnValue(
286324
createSuccessfulRemoteDataObject$({
287-
... new ConfigurationProperty(),
325+
...new ConfigurationProperty(),
288326
name: googleAnalytics,
289327
values: [],
290328
}));
291329

292330
service.initialize();
293-
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({name: googleAnalytics}));
331+
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
294332
});
295333
it('should filter googleAnalytics when an error occurs', () => {
296334
configurationDataService.findByPropertyName = jasmine.createSpy().withArgs(GOOGLE_ANALYTICS_KEY).and.returnValue(
297335
createFailedRemoteDataObject$('Erro while loading GA')
298336
);
299337
service.initialize();
300-
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({name: googleAnalytics}));
338+
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
301339
});
302340
it('should filter googleAnalytics when an invalid payload is retrieved', () => {
303341
configurationDataService.findByPropertyName = jasmine.createSpy().withArgs(GOOGLE_ANALYTICS_KEY).and.returnValue(
304342
createSuccessfulRemoteDataObject$(null)
305343
);
306344
service.initialize();
307-
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({name: googleAnalytics}));
345+
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
308346
});
309347
});
310348
});

src/app/shared/cookies/browser-klaro.service.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { EPersonDataService } from '../../core/eperson/eperson-data.service';
1313
import { cloneDeep, debounce } from 'lodash';
1414
import { ANONYMOUS_STORAGE_NAME_KLARO, klaroConfiguration } from './klaro-configuration';
1515
import { Operation } from 'fast-json-patch';
16-
import { getFirstCompletedRemoteData} from '../../core/shared/operators';
16+
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
1717
import { ConfigurationDataService } from '../../core/data/configuration-data.service';
1818

1919
/**
@@ -121,6 +121,23 @@ export class BrowserKlaroService extends KlaroService {
121121
});
122122
}
123123

124+
/**
125+
* Return saved preferences stored in the klaro cookie
126+
*/
127+
getSavedPreferences(): Observable<any> {
128+
return this.getUser$().pipe(
129+
map((user: EPerson) => {
130+
let storageName;
131+
if (isEmpty(user)) {
132+
storageName = ANONYMOUS_STORAGE_NAME_KLARO;
133+
} else {
134+
storageName = this.getStorageName(user.uuid);
135+
}
136+
return this.cookieService.get(storageName);
137+
})
138+
);
139+
}
140+
124141
/**
125142
* Initialize configuration for the logged in user
126143
* @param user The authenticated user

src/app/shared/cookies/klaro-configuration.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export const HAS_AGREED_END_USER = 'dsHasAgreedEndUser';
1212
*/
1313
export const ANONYMOUS_STORAGE_NAME_KLARO = 'klaro-anonymous';
1414

15+
export const GOOGLE_ANALYTICS_KLARO_KEY = 'google-analytics';
16+
1517
/**
1618
* Klaro configuration
1719
* For more information see https://kiprotect.com/docs/klaro/annotated-config
@@ -113,7 +115,7 @@ export const klaroConfiguration: any = {
113115
]
114116
},
115117
{
116-
name: 'google-analytics',
118+
name: GOOGLE_ANALYTICS_KLARO_KEY,
117119
purposes: ['statistical'],
118120
required: false,
119121
cookies: [

src/app/shared/cookies/klaro.service.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { Injectable } from '@angular/core';
22

3+
import { Observable } from 'rxjs';
4+
35
/**
46
* Abstract class representing a service for handling Klaro consent preferences and UI
57
*/
@@ -11,7 +13,12 @@ export abstract class KlaroService {
1113
abstract initialize();
1214

1315
/**
14-
* Shows a the dialog with the current consent preferences
16+
* Shows a dialog with the current consent preferences
1517
*/
1618
abstract showSettings();
19+
20+
/**
21+
* Return saved preferences stored in the klaro cookie
22+
*/
23+
abstract getSavedPreferences(): Observable<any>;
1724
}

0 commit comments

Comments
 (0)