mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
349 lines
13 KiB
TypeScript
349 lines
13 KiB
TypeScript
import { TestBed } from '@angular/core/testing';
|
|
import { BrowserKlaroService, COOKIE_MDFIELD } from './browser-klaro.service';
|
|
import { getMockTranslateService } from '../mocks/translate.service.mock';
|
|
import { of as observableOf } from 'rxjs';
|
|
import { RestResponse } from '../../core/cache/response.models';
|
|
import { EPerson } from '../../core/eperson/models/eperson.model';
|
|
import { TranslateService } from '@ngx-translate/core';
|
|
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
|
|
import { AuthService } from '../../core/auth/auth.service';
|
|
import { CookieService } from '../../core/services/cookie.service';
|
|
import { getTestScheduler } from 'jasmine-marbles';
|
|
import { MetadataValue } from '../../core/shared/metadata.models';
|
|
import { clone, cloneDeep } from 'lodash';
|
|
import { ConfigurationDataService } from '../../core/data/configuration-data.service';
|
|
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../remote-data.utils';
|
|
import { ConfigurationProperty } from '../../core/shared/configuration-property.model';
|
|
import { ANONYMOUS_STORAGE_NAME_KLARO } from './klaro-configuration';
|
|
import { TestScheduler } from 'rxjs/testing';
|
|
|
|
describe('BrowserKlaroService', () => {
|
|
const trackingIdProp = 'google.analytics.key';
|
|
const trackingIdTestValue = 'mock-tracking-id';
|
|
const googleAnalytics = 'google-analytics';
|
|
let translateService;
|
|
let ePersonService;
|
|
let authService;
|
|
let cookieService;
|
|
|
|
let user;
|
|
let service: BrowserKlaroService;
|
|
let configurationDataService: ConfigurationDataService;
|
|
const createConfigSuccessSpy = (...values: string[]) => jasmine.createSpyObj('configurationDataService', {
|
|
findByPropertyName: createSuccessfulRemoteDataObject$({
|
|
...new ConfigurationProperty(),
|
|
name: trackingIdProp,
|
|
values: values,
|
|
}),
|
|
});
|
|
|
|
let mockConfig;
|
|
let appName;
|
|
let purpose;
|
|
let testKey;
|
|
let findByPropertyName;
|
|
|
|
beforeEach(() => {
|
|
user = Object.assign(new EPerson(), {
|
|
uuid: 'test-user'
|
|
});
|
|
|
|
translateService = getMockTranslateService();
|
|
ePersonService = jasmine.createSpyObj('ePersonService', {
|
|
createPatchFromCache: observableOf([]),
|
|
patch: observableOf(new RestResponse(true, 200, 'Ok'))
|
|
});
|
|
authService = jasmine.createSpyObj('authService', {
|
|
isAuthenticated: observableOf(true),
|
|
getAuthenticatedUserFromStore: observableOf(user)
|
|
});
|
|
configurationDataService = createConfigSuccessSpy(trackingIdTestValue);
|
|
findByPropertyName = configurationDataService.findByPropertyName;
|
|
cookieService = jasmine.createSpyObj('cookieService', {
|
|
get: '{%22token_item%22:true%2C%22impersonation%22:true%2C%22redirect%22:true%2C%22language%22:true%2C%22klaro%22:true%2C%22has_agreed_end_user%22:true%2C%22google-analytics%22:true}',
|
|
set: () => {
|
|
/* empty */
|
|
}
|
|
});
|
|
|
|
TestBed.configureTestingModule({
|
|
providers: [
|
|
BrowserKlaroService,
|
|
{
|
|
provide: TranslateService,
|
|
useValue: translateService
|
|
},
|
|
{
|
|
provide: EPersonDataService,
|
|
useValue: ePersonService,
|
|
},
|
|
{
|
|
provide: AuthService,
|
|
useValue: authService
|
|
},
|
|
{
|
|
provide: CookieService,
|
|
useValue: cookieService
|
|
},
|
|
{
|
|
provide: ConfigurationDataService,
|
|
useValue: configurationDataService
|
|
}
|
|
]
|
|
});
|
|
service = TestBed.inject(BrowserKlaroService);
|
|
appName = 'testName';
|
|
purpose = 'test purpose';
|
|
testKey = 'this.is.a.fake.message.key';
|
|
|
|
mockConfig = {
|
|
translations: {
|
|
en: {
|
|
purposes: {},
|
|
test: {
|
|
testeritis: testKey
|
|
}
|
|
}
|
|
},
|
|
services: [{
|
|
name: appName,
|
|
purposes: [purpose]
|
|
}, {
|
|
name: googleAnalytics,
|
|
purposes: [purpose]
|
|
}],
|
|
|
|
};
|
|
|
|
service.klaroConfig = mockConfig;
|
|
});
|
|
|
|
it('should be created', () => {
|
|
expect(service).toBeTruthy();
|
|
});
|
|
|
|
describe('initialize with user', () => {
|
|
beforeEach(() => {
|
|
spyOn((service as any), 'getUser$').and.returnValue(observableOf(user));
|
|
translateService.get.and.returnValue(observableOf('loading...'));
|
|
spyOn(service, 'addAppMessages');
|
|
spyOn((service as any), 'initializeUser');
|
|
spyOn(service, 'translateConfiguration');
|
|
});
|
|
it('to call the initialize user method and other methods', () => {
|
|
service.initialize();
|
|
expect((service as any).initializeUser).toHaveBeenCalledWith(user);
|
|
expect(service.addAppMessages).toHaveBeenCalled();
|
|
expect(service.translateConfiguration).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('to not call the initialize user method, but the other methods', () => {
|
|
beforeEach(() => {
|
|
spyOn((service as any), 'getUser$').and.returnValue(observableOf(undefined));
|
|
translateService.get.and.returnValue(observableOf('loading...'));
|
|
spyOn(service, 'addAppMessages');
|
|
spyOn((service as any), 'initializeUser');
|
|
spyOn(service, 'translateConfiguration');
|
|
});
|
|
it('to call all ', () => {
|
|
service.initialize();
|
|
expect((service as any).initializeUser).not.toHaveBeenCalledWith(user);
|
|
expect(service.addAppMessages).toHaveBeenCalled();
|
|
expect(service.translateConfiguration).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
it('addAppMessages', () => {
|
|
service.addAppMessages();
|
|
expect(mockConfig.translations.en[appName]).toBeDefined();
|
|
expect(mockConfig.translations.en.purposes[purpose]).toBeDefined();
|
|
});
|
|
|
|
it('translateConfiguration', () => {
|
|
service.translateConfiguration();
|
|
expect((service as any).translateService.instant).toHaveBeenCalledWith(testKey);
|
|
});
|
|
|
|
describe('initializeUser when there is a metadata field value', () => {
|
|
beforeEach(() => {
|
|
user.setMetadata(COOKIE_MDFIELD, undefined, '{}');
|
|
spyOn(service, 'restoreSettingsForUsers');
|
|
});
|
|
|
|
it('initializeUser', () => {
|
|
(service as any).initializeUser(user);
|
|
expect(service.restoreSettingsForUsers).toHaveBeenCalledWith(user);
|
|
});
|
|
});
|
|
|
|
describe('initializeUser when there is no metadata field value but there is an anonymous cookie', () => {
|
|
const cookie = '{test: \'testt\'}';
|
|
beforeEach(() => {
|
|
(service as any).cookieService.get.and.returnValue(cookie);
|
|
spyOn(service, 'updateSettingsForUsers');
|
|
});
|
|
|
|
it('initializeUser', () => {
|
|
(service as any).initializeUser(user);
|
|
expect((service as any).cookieService.set).toHaveBeenCalledWith(service.getStorageName(user.uuid), cookie);
|
|
expect(service.updateSettingsForUsers).toHaveBeenCalledWith(user);
|
|
});
|
|
});
|
|
|
|
describe('getUser$ when there is no one authenticated', () => {
|
|
beforeEach(() => {
|
|
(service as any).authService.isAuthenticated.and.returnValue(observableOf(false));
|
|
});
|
|
it('should return undefined', () => {
|
|
getTestScheduler().expectObservable((service as any).getUser$()).toBe('(a|)', { a: undefined });
|
|
});
|
|
});
|
|
|
|
describe('getUser$ when there someone is authenticated', () => {
|
|
beforeEach(() => {
|
|
(service as any).authService.isAuthenticated.and.returnValue(observableOf(true));
|
|
(service as any).authService.getAuthenticatedUserFromStore.and.returnValue(observableOf(user));
|
|
});
|
|
it('should return the user', () => {
|
|
getTestScheduler().expectObservable((service as any).getUser$()).toBe('(a|)', { a: user });
|
|
});
|
|
});
|
|
|
|
describe('getSettingsForUser', () => {
|
|
const cookieConsentString = '{test: \'testt\'}';
|
|
beforeEach(() => {
|
|
user.metadata = {};
|
|
user.metadata[COOKIE_MDFIELD] = [Object.assign(new MetadataValue(), { value: cookieConsentString })];
|
|
spyOn(JSON, 'parse');
|
|
});
|
|
it('should return the cookie consents object', () => {
|
|
service.getSettingsForUser(user);
|
|
expect(JSON.parse).toHaveBeenCalledWith(cookieConsentString);
|
|
});
|
|
});
|
|
|
|
describe('getSavedPreferences', () => {
|
|
let scheduler: TestScheduler;
|
|
beforeEach(() => {
|
|
scheduler = getTestScheduler();
|
|
});
|
|
|
|
describe('when no user is autheticated', () => {
|
|
beforeEach(() => {
|
|
spyOn(service as any, 'getUser$').and.returnValue(observableOf(undefined));
|
|
});
|
|
|
|
it('should return the cookie consents object', () => {
|
|
scheduler.schedule(() => service.getSavedPreferences().subscribe());
|
|
scheduler.flush();
|
|
|
|
expect(cookieService.get).toHaveBeenCalledWith(ANONYMOUS_STORAGE_NAME_KLARO);
|
|
});
|
|
});
|
|
|
|
describe('when user is autheticated', () => {
|
|
beforeEach(() => {
|
|
spyOn(service as any, 'getUser$').and.returnValue(observableOf(user));
|
|
});
|
|
|
|
it('should return the cookie consents object', () => {
|
|
scheduler.schedule(() => service.getSavedPreferences().subscribe());
|
|
scheduler.flush();
|
|
|
|
expect(cookieService.get).toHaveBeenCalledWith('klaro-' + user.uuid);
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
describe('setSettingsForUser when there are changes', () => {
|
|
const cookieConsent = { test: 'testt' };
|
|
const cookieConsentString = '{test: \'testt\'}';
|
|
const operation = { op: 'add', path: 'metadata/dc.agreements.cookie', value: cookieConsentString };
|
|
let updatedUser;
|
|
|
|
beforeEach(() => {
|
|
updatedUser = cloneDeep(user);
|
|
|
|
spyOn(updatedUser, 'setMetadata');
|
|
spyOn(JSON, 'stringify').and.returnValue(cookieConsentString);
|
|
ePersonService.createPatchFromCache.and.returnValue(observableOf([operation]));
|
|
});
|
|
it('should call patch on the data service', () => {
|
|
service.setSettingsForUser(updatedUser, cookieConsent);
|
|
expect(updatedUser.setMetadata).toHaveBeenCalledWith(COOKIE_MDFIELD, undefined, cookieConsentString);
|
|
expect(ePersonService.patch).toHaveBeenCalledWith(updatedUser, [operation]);
|
|
});
|
|
});
|
|
|
|
describe('setSettingsForUser when there are no changes', () => {
|
|
const cookieConsent = { test: 'testt' };
|
|
const cookieConsentString = '{test: \'testt\'}';
|
|
let updatedUser;
|
|
|
|
beforeEach(() => {
|
|
updatedUser = cloneDeep(user);
|
|
|
|
spyOn(updatedUser, 'setMetadata');
|
|
spyOn(JSON, 'stringify').and.returnValue(cookieConsentString);
|
|
ePersonService.createPatchFromCache.and.returnValue(observableOf([]));
|
|
});
|
|
it('should not call patch on the data service', () => {
|
|
service.setSettingsForUser(updatedUser, cookieConsent);
|
|
expect(updatedUser.setMetadata).toHaveBeenCalledWith(COOKIE_MDFIELD, undefined, cookieConsentString);
|
|
expect(ePersonService.patch).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('initialize google analytics configuration', () => {
|
|
let GOOGLE_ANALYTICS_KEY;
|
|
beforeEach(() => {
|
|
GOOGLE_ANALYTICS_KEY = clone((service as any).GOOGLE_ANALYTICS_KEY);
|
|
configurationDataService.findByPropertyName = findByPropertyName;
|
|
spyOn((service as any), 'getUser$').and.returnValue(observableOf(user));
|
|
translateService.get.and.returnValue(observableOf('loading...'));
|
|
spyOn(service, 'addAppMessages');
|
|
spyOn((service as any), 'initializeUser');
|
|
spyOn(service, 'translateConfiguration');
|
|
});
|
|
it('should not filter googleAnalytics when servicesToHide are empty', () => {
|
|
const filteredConfig = (service as any).filterConfigServices([]);
|
|
expect(filteredConfig).toContain(jasmine.objectContaining({ name: googleAnalytics }));
|
|
});
|
|
it('should filter services using names passed as servicesToHide', () => {
|
|
const filteredConfig = (service as any).filterConfigServices([googleAnalytics]);
|
|
expect(filteredConfig).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
|
|
});
|
|
it('should have been initialized with googleAnalytics', () => {
|
|
service.initialize();
|
|
expect(service.klaroConfig.services).toContain(jasmine.objectContaining({ name: googleAnalytics }));
|
|
});
|
|
it('should filter googleAnalytics when empty configuration is retrieved', () => {
|
|
configurationDataService.findByPropertyName = jasmine.createSpy().withArgs(GOOGLE_ANALYTICS_KEY).and.returnValue(
|
|
createSuccessfulRemoteDataObject$({
|
|
...new ConfigurationProperty(),
|
|
name: googleAnalytics,
|
|
values: [],
|
|
}));
|
|
|
|
service.initialize();
|
|
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
|
|
});
|
|
it('should filter googleAnalytics when an error occurs', () => {
|
|
configurationDataService.findByPropertyName = jasmine.createSpy().withArgs(GOOGLE_ANALYTICS_KEY).and.returnValue(
|
|
createFailedRemoteDataObject$('Erro while loading GA')
|
|
);
|
|
service.initialize();
|
|
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
|
|
});
|
|
it('should filter googleAnalytics when an invalid payload is retrieved', () => {
|
|
configurationDataService.findByPropertyName = jasmine.createSpy().withArgs(GOOGLE_ANALYTICS_KEY).and.returnValue(
|
|
createSuccessfulRemoteDataObject$(null)
|
|
);
|
|
service.initialize();
|
|
expect(service.klaroConfig.services).not.toContain(jasmine.objectContaining({ name: googleAnalytics }));
|
|
});
|
|
});
|
|
});
|