Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
1 change: 1 addition & 0 deletions src/persistence.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export interface IPersistence {
getUserProductsFromLS(mpid: MPID): Product[];
getAllUserProductsFromLS(): Product[];
setLocalStorage(): void;
setProductStorage(): void;
getLocalStorage(): IPersistenceMinified | null;
expireCookies(cookieName: string): void;
getCookie(): IPersistenceMinified | null;
Expand Down
37 changes: 24 additions & 13 deletions src/persistence.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export default function _Persistence(mpInstance) {
if (!mpInstance._Store.isLocalStorageAvailable) {
mpInstance._Store.SDKConfig.useCookieStorage = true;
}
if (mpInstance._Store.getPrivacyFlag('SDKState')) {
Comment thread
jaissica12 marked this conversation as resolved.
Outdated
return;
}

// https://go.mparticle.com/work/SQDSDKS-6046
if (mpInstance._Store.isLocalStorageAvailable) {
Expand Down Expand Up @@ -86,6 +89,17 @@ export default function _Persistence(mpInstance) {
self.storeDataInMemory(cookies);
}

// https://go.mparticle.com/work/SQDSDKS-6046
// Stores all non-current user MPID information into the store
for (var key in allData) {
if (allData.hasOwnProperty(key)) {
if (!SDKv2NonMPIDCookieKeys[key]) {
mpInstance._Store.nonCurrentUserMPIDs[key] =
allData[key];
}
}
}
Comment thread
jaissica12 marked this conversation as resolved.
Outdated

// https://go.mparticle.com/work/SQDSDKS-6048
try {
if (mpInstance._Store.isLocalStorageAvailable) {
Expand Down Expand Up @@ -114,17 +128,6 @@ export default function _Persistence(mpInstance) {
'Error loading products in initialization: ' + e
);
}

// https://go.mparticle.com/work/SQDSDKS-6046
// Stores all non-current user MPID information into the store
for (var key in allData) {
if (allData.hasOwnProperty(key)) {
if (!SDKv2NonMPIDCookieKeys[key]) {
mpInstance._Store.nonCurrentUserMPIDs[key] =
allData[key];
}
}
}
self.update();
} catch (e) {
// If cookies or local storage is corrupt, we want to remove it
Expand All @@ -142,11 +145,13 @@ export default function _Persistence(mpInstance) {
};

this.update = function() {
if (!mpInstance._Store.webviewBridgeEnabled) {
if (
!mpInstance._Store.webviewBridgeEnabled &&
!mpInstance._Store.getPrivacyFlag('SDKState')
) {
if (mpInstance._Store.SDKConfig.useCookieStorage) {
self.setCookie();
}

self.setLocalStorage();
}
};
Expand Down Expand Up @@ -962,6 +967,9 @@ export default function _Persistence(mpInstance) {

// https://go.mparticle.com/work/SQDSDKS-6021
this.savePersistence = function(persistence) {
if (mpInstance._Store.getPrivacyFlag('SDKState')) {
return;
}
var encodedPersistence = self.encodePersistence(
JSON.stringify(persistence)
),
Expand Down Expand Up @@ -1006,6 +1014,9 @@ export default function _Persistence(mpInstance) {
};

this.getPersistence = function() {
if (mpInstance._Store.getPrivacyFlag('SDKState')) {
return null;
}
var persistence = this.useLocalStorage()
? this.getLocalStorage()
: this.getCookie();
Expand Down
145 changes: 145 additions & 0 deletions test/jest/persistence.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import Store, { IStore } from '../../src/store';
import { IMParticleWebSDKInstance } from '../../src/mp-instance';
import { SDKInitConfig } from '../../src/sdkRuntimeModels';

describe('Persistence store', () => {
Comment thread
jaissica12 marked this conversation as resolved.
Outdated
let store: IStore;
let mockMPInstance: IMParticleWebSDKInstance;

beforeEach(() => {
mockMPInstance = {
Comment thread
alexs-mparticle marked this conversation as resolved.
_Helpers: {
createMainStorageName: () => 'mprtcl-v4',
Validators: { isFunction: () => true },
extend: Object.assign,
},
_NativeSdkHelpers: {
isWebviewEnabled: () => false,
},
_Persistence: {
setCookie: jest.fn(),
setLocalStorage: jest.fn(() => {
window.localStorage.setItem('mprtcl-v4', 'local-storage');
}),
update: function () {
if (store.webviewBridgeEnabled || store.getNoFunctional()) {
return;
}
if (store.SDKConfig.useCookieStorage) {
mockMPInstance._Persistence.setCookie();
}
mockMPInstance._Persistence.setLocalStorage();
},
Comment thread
jaissica12 marked this conversation as resolved.
Outdated
},
Logger: {
verbose: () => {},
warning: () => {},
error: () => {},
},
Identity: {
getCurrentUser: () => ({ getMPID: () => 'mpid' }),
},
} as unknown as IMParticleWebSDKInstance;

store = {} as IStore;
Store.call(store, {} as SDKInitConfig, mockMPInstance, 'apikey');
window.localStorage.removeItem('mprtcl-v4');
});

describe('#noFunctional privacy flag', () => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
describe('#noFunctional privacy flag', () => {
describe('#update', () => {

describe('true', () => {
Comment thread
jaissica12 marked this conversation as resolved.
Outdated
beforeEach(() => {
store.setNoFunctional(true);
store.webviewBridgeEnabled = false;
});

it('should NOT write to cookie and localStorage when useCookieStorage is true', () => {
store.SDKConfig.useCookieStorage = true;

mockMPInstance._Persistence.update();

expect(mockMPInstance._Persistence.setCookie).not.toHaveBeenCalled();
expect(mockMPInstance._Persistence.setLocalStorage).not.toHaveBeenCalled();
expect(window.localStorage.getItem('mprtcl-v4')).toBeNull();
});

it('should NOT write to localStorage when useCookieStorage is false', () => {
store.SDKConfig.useCookieStorage = false;

mockMPInstance._Persistence.update();

expect(mockMPInstance._Persistence.setCookie).not.toHaveBeenCalled();
expect(mockMPInstance._Persistence.setLocalStorage).not.toHaveBeenCalled();
expect(window.localStorage.getItem('mprtcl-v4')).toBeNull();
});
});

describe('false', () => {
Comment thread
jaissica12 marked this conversation as resolved.
Outdated
beforeEach(() => {
store.setNoFunctional(false);
store.webviewBridgeEnabled = false;
});

it('should write to cookie and localStorage when useCookieStorage is true', () => {
store.SDKConfig.useCookieStorage = true;

mockMPInstance._Persistence.update();

expect(mockMPInstance._Persistence.setCookie).toHaveBeenCalled();
expect(mockMPInstance._Persistence.setLocalStorage).toHaveBeenCalled();
expect(window.localStorage.getItem('mprtcl-v4')).not.toBeNull();
});

it('should write to localStorage when useCookieStorage is false', () => {
store.SDKConfig.useCookieStorage = false;

mockMPInstance._Persistence.update();

expect(mockMPInstance._Persistence.setCookie).not.toHaveBeenCalled();
expect(mockMPInstance._Persistence.setLocalStorage).toHaveBeenCalled();
Comment thread
rmi22186 marked this conversation as resolved.
Outdated
expect(window.localStorage.getItem('mprtcl-v4')).not.toBeNull();
});
});

describe('is false by default', () => {
Comment thread
jaissica12 marked this conversation as resolved.
Outdated
beforeEach(() => {
// default is false
store.webviewBridgeEnabled = false;
});

it('should write to cookie and localStorage by default when useCookieStorage is true', () => {
Comment thread
alexs-mparticle marked this conversation as resolved.
store.SDKConfig.useCookieStorage = true;

mockMPInstance._Persistence.update();

expect(store.getNoFunctional()).toBe(false);
expect(mockMPInstance._Persistence.setCookie).toHaveBeenCalled();
expect(mockMPInstance._Persistence.setLocalStorage).toHaveBeenCalled();
expect(window.localStorage.getItem('mprtcl-v4')).not.toBeNull();
});

it('should write to localStorage by default when useCookieStorage is false', () => {
store.SDKConfig.useCookieStorage = false;

mockMPInstance._Persistence.update();

expect(store.getNoFunctional()).toBe(false);
expect(mockMPInstance._Persistence.setCookie).not.toHaveBeenCalled();
expect(mockMPInstance._Persistence.setLocalStorage).toHaveBeenCalled();
expect(window.localStorage.getItem('mprtcl-v4')).not.toBeNull();
});
});

it('should NOT write to storage when webviewBridgeEnabled is true', () => {
store.setNoFunctional(false);
store.webviewBridgeEnabled = true;
store.SDKConfig.useCookieStorage = true;

mockMPInstance._Persistence.update();

expect(mockMPInstance._Persistence.setCookie).not.toHaveBeenCalled();
expect(mockMPInstance._Persistence.setLocalStorage).not.toHaveBeenCalled();
expect(window.localStorage.getItem('mprtcl-v4')).toBeNull();
});
});
});
86 changes: 86 additions & 0 deletions test/src/tests-persistence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1948,4 +1948,90 @@ describe('persistence', () => {
user2.getAllUserAttributes()['ua-list'][1].should.equal('<b>');
user2.getAllUserAttributes()['ua-1'].should.equal('a');
});

describe('#noFunctional', () => {
Comment thread
jaissica12 marked this conversation as resolved.
Outdated
beforeEach(() => {
mParticle._resetForTests(MPConfig);
});

describe('true', () => {
Comment thread
jaissica12 marked this conversation as resolved.
Outdated
beforeEach(() => {
mParticle.config.launcherOptions = { noFunctional: true };
});

it('should NOT store cookie when useCookieStorage = true', async () => {
Comment thread
jaissica12 marked this conversation as resolved.
mParticle.config.useCookieStorage = true;

mParticle.init(apiKey, mParticle.config);
await waitForCondition(hasIdentifyReturned);

mParticle.getInstance()._Persistence.update();

expect(findCookie()).to.not.be.ok;
});

it('should NOT write localStorage when useCookieStorage = false', async () => {
mParticle.config.useCookieStorage = false;

mParticle.init(apiKey, mParticle.config);
await waitForCondition(hasIdentifyReturned);

mParticle.getInstance()._Persistence.update();

expect(getLocalStorage()).to.not.be.ok;
});
});

describe('false', () => {
Comment thread
jaissica12 marked this conversation as resolved.
Outdated
beforeEach(() => {
mParticle.config.launcherOptions = { noFunctional: false };
});

it('should store cookie when useCookieStorage = true', async () => {
Comment thread
jaissica12 marked this conversation as resolved.
mParticle.config.useCookieStorage = true;

mParticle.init(apiKey, mParticle.config);
await waitForCondition(hasIdentifyReturned);

mParticle.getInstance()._Persistence.update();

expect(findCookie()).to.be.ok;
});

it('should store localStorage when useCookieStorage = false', async () => {
mParticle.config.useCookieStorage = false;

mParticle.init(apiKey, mParticle.config);
await waitForCondition(hasIdentifyReturned);

mParticle.getInstance()._Persistence.update();

expect(getLocalStorage()).to.be.ok;
});
});

describe('is false by default', () => {
it('should store cookie when useCookieStorage = true', async () => {
mParticle.config.useCookieStorage = true;

mParticle.init(apiKey, mParticle.config);
await waitForCondition(hasIdentifyReturned);

mParticle.getInstance()._Persistence.update();

expect(findCookie()).to.be.ok;
});

it('should store localStorage when useCookieStorage = false', async () => {
mParticle.config.useCookieStorage = false;

mParticle.init(apiKey, mParticle.config);
await waitForCondition(hasIdentifyReturned);

mParticle.getInstance()._Persistence.update();

expect(getLocalStorage()).to.be.ok;
});
});
});
});
Loading