Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -740,9 +740,21 @@ export default function Store(
this.SDKConfig[baseUrlKeys] = baseUrls[baseUrlKeys];
}

const { noFunctional, noTargeting } = config?.launcherOptions ?? {};

if (noFunctional != null) {
this.setNoFunctional(noFunctional);
}

if (noTargeting != null) {
this.setNoTargeting(noTargeting);
}

if (workspaceToken) {
this.SDKConfig.workspaceToken = workspaceToken;
mpInstance._timeOnSiteTimer = new ForegroundTimer(workspaceToken);
if (!this.getPrivacyFlag('TimeOnSite')) {
mpInstance._timeOnSiteTimer = new ForegroundTimer(workspaceToken);
}
} else {
mpInstance.Logger.warning(
'You should have a workspaceToken on your config object for security purposes.'
Expand All @@ -752,15 +764,6 @@ export default function Store(
this.storageName = createMainStorageName(workspaceToken);
this.prodStorageName = createProductStorageName(workspaceToken);

// Extract privacy flags directly from config into Store
if (config.hasOwnProperty('noFunctional')) {
this.setNoFunctional(config.noFunctional);
}

if (config.hasOwnProperty('noTargeting')) {
this.setNoTargeting(config.noTargeting);
}

this.SDKConfig.requiredWebviewBridgeName =
requiredWebviewBridgeName || workspaceToken;

Expand Down
64 changes: 64 additions & 0 deletions test/jest/foregroundTimeTracker.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import ForegroundTimeTracker from '../../src/foregroundTimeTracker';
import Store, { IStore } from '../../src/store';
import { SDKInitConfig } from '../../src/sdkRuntimeModels';
import { IMParticleWebSDKInstance } from '../../src/mp-instance';

describe('ForegroundTimeTracker', () => {
let foregroundTimeTracker: ForegroundTimeTracker;
Expand Down Expand Up @@ -490,4 +493,65 @@ describe('ForegroundTimeTracker', () => {
expect(updatePersistenceSpy).toHaveBeenCalled();
});
});

describe('#privacy flags', () => {
const workspaceToken = 'abcdef';
const tosKey = `mprtcl-tos-${workspaceToken}`;
let mockMPInstance: IMParticleWebSDKInstance;
let store: IStore;

beforeEach(() => {
jest.useFakeTimers({ now: Date.now(), advanceTimers: true });
localStorage.clear();

mockMPInstance = {
_Helpers: {
createMainStorageName: () => `mprtcl-v4_${workspaceToken}`,
createProductStorageName: () => `mprtcl-prodv4_${workspaceToken}`,
Validators: { isFunction: () => true },
extend: Object.assign,
},
_NativeSdkHelpers: { isWebviewEnabled: () => false },
_Persistence: {
update: jest.fn(),
savePersistence: jest.fn(),
getPersistence: () => ({ gs: {} }),
},
Logger: { verbose: jest.fn(), warning: jest.fn(), error: jest.fn() },
Identity: { getCurrentUser: () => ({ getMPID: () => 'mpid' }) },
_timeOnSiteTimer: undefined as any,
} as unknown as IMParticleWebSDKInstance;

store = {} as IStore;
(Store as any).call(store, {} as SDKInitConfig, mockMPInstance, 'apikey');
mockMPInstance._Store = store;
});

afterEach(() => {
jest.useRealTimers();
localStorage.clear();
});

it('should track time on site when noTargeting is false by default', () => {
store.processConfig({ workspaceToken } as SDKInitConfig);
expect(mockMPInstance._timeOnSiteTimer).toBeDefined();
jest.advanceTimersByTime(1000);
mockMPInstance._timeOnSiteTimer.getTimeInForeground();
expect(localStorage.getItem(tosKey)).not.toBeNull();
});

it('should NOT track time on site when noTargeting is true', () => {
store.processConfig({ workspaceToken, launcherOptions: { noTargeting: true } } as SDKInitConfig);
expect(mockMPInstance._timeOnSiteTimer).toBeUndefined();
expect(localStorage.getItem(tosKey)).toBeNull();
});

it('should track time on site when noTargeting is false', () => {
store.processConfig({ workspaceToken, launcherOptions: { noTargeting: false } } as SDKInitConfig);
expect(mockMPInstance._timeOnSiteTimer).toBeDefined();
jest.advanceTimersByTime(1000);
mockMPInstance._timeOnSiteTimer.getTimeInForeground();
expect(localStorage.getItem(tosKey)).not.toBeNull();
});
});
});
11 changes: 4 additions & 7 deletions test/jest/store.flags.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ describe('Store privacy flags', () => {

it('should set noFunctional as true and noTargeting as true from config', () => {
const cfg: SDKInitConfig = {
noFunctional: true,
noTargeting: true,
launcherOptions: { noFunctional: true, noTargeting: true },
flags: {},
} as any;

Expand All @@ -59,8 +58,7 @@ describe('Store privacy flags', () => {

it('should set noFunctional as true and noTargeting as false from config', () => {
const cfg: SDKInitConfig = {
noFunctional: true,
noTargeting: false,
launcherOptions: { noFunctional: true, noTargeting: false },
flags: {},
} as any;

Expand All @@ -72,13 +70,12 @@ describe('Store privacy flags', () => {

it('should set noFunctional as false and noTargeting as true from config', () => {
const cfg: SDKInitConfig = {
noFunctional: false,
noTargeting: true,
launcherOptions: { noFunctional: false, noTargeting: true },
flags: {},
} as any;

store.processConfig(cfg);

expect(store.getNoFunctional()).toBe(false);
expect(store.getNoTargeting()).toBe(true);
});
Expand Down
8 changes: 4 additions & 4 deletions test/src/tests-batchUploader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1744,7 +1744,7 @@ describe('batch uploader', () => {
offlineStorage: '100',
...enableBatchingConfigFlags,
};
window.mParticle.config.noFunctional = true;
window.mParticle.config.launcherOptions = { noFunctional: true };
window.mParticle.init(apiKey, window.mParticle.config);
await waitForCondition(hasIdentifyReturned);
const mpInstance = window.mParticle.getInstance();
Expand All @@ -1758,7 +1758,7 @@ describe('batch uploader', () => {
offlineStorage: '100',
...enableBatchingConfigFlags,
};
window.mParticle.config.noFunctional = false;
window.mParticle.config.launcherOptions = { noFunctional: false };
window.mParticle.init(apiKey, window.mParticle.config);
await waitForCondition(hasIdentifyReturned);
const mpInstance = window.mParticle.getInstance();
Expand All @@ -1783,7 +1783,7 @@ describe('batch uploader', () => {
offlineStorage: '100',
...enableBatchingConfigFlags,
};
window.mParticle.config.noFunctional = true;
window.mParticle.config.launcherOptions = { noFunctional: true };
window.mParticle.init(apiKey, window.mParticle.config);
await waitForCondition(hasIdentifyReturned);
const mpInstance = window.mParticle.getInstance();
Expand All @@ -1798,7 +1798,7 @@ describe('batch uploader', () => {
offlineStorage: '100',
...enableBatchingConfigFlags,
};
window.mParticle.config.noFunctional = false;
window.mParticle.config.launcherOptions = { noFunctional: false };
window.mParticle.init(apiKey, window.mParticle.config);
await waitForCondition(hasIdentifyReturned);
const mpInstance = window.mParticle.getInstance();
Expand Down
3 changes: 1 addition & 2 deletions test/src/tests-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1817,8 +1817,7 @@ describe('Store', () => {
it('should set noFunctional and noTargeting from init config', () => {
window.mParticle._resetForTests(MPConfig);
window.mParticle.config = window.mParticle.config || {};
window.mParticle.config.noFunctional = true;
window.mParticle.config.noTargeting = true;
window.mParticle.config.launcherOptions = { noFunctional: true, noTargeting: true };

window.mParticle.init(apiKey, window.mParticle.config);

Expand Down
Loading