diff --git a/src/persistence.js b/src/persistence.js index cb40e2f8e..8f2bcacef 100644 --- a/src/persistence.js +++ b/src/persistence.js @@ -88,7 +88,10 @@ export default function _Persistence(mpInstance) { // https://go.mparticle.com/work/SQDSDKS-6048 try { - if (mpInstance._Store.isLocalStorageAvailable) { + if ( + mpInstance._Store.isLocalStorageAvailable && + !mpInstance._Store.getPrivacyFlag('Products') + ) { var encodedProducts = localStorage.getItem( mpInstance._Store.prodStorageName ); @@ -269,7 +272,10 @@ export default function _Persistence(mpInstance) { }; this.getUserProductsFromLS = function(mpid) { - if (!mpInstance._Store.isLocalStorageAvailable) { + if ( + mpInstance._Store.getPrivacyFlag('Products') || + !mpInstance._Store.isLocalStorageAvailable + ) { return []; } @@ -308,6 +314,15 @@ export default function _Persistence(mpInstance) { }; this.getAllUserProductsFromLS = function() { + if (mpInstance._Store.getPrivacyFlag('Products')) { + var currentUser = mpInstance.Identity.getCurrentUser(); + var mpid = currentUser ? currentUser.getMPID() : null; + var result = {}; + if (mpid) { + result[mpid] = { cp: [] }; + } + return result; + } var decodedProducts, encodedProducts = localStorage.getItem( mpInstance._Store.prodStorageName @@ -342,14 +357,21 @@ export default function _Persistence(mpInstance) { ? allLocalStorageProducts[mpid].cp : [], }; + + if (mpInstance._Store.getPrivacyFlag('Products')) { + return; + } if (mpid) { allLocalStorageProducts = allLocalStorageProducts || {}; allLocalStorageProducts[mpid] = currentUserProducts; try { - window.localStorage.setItem( - encodeURIComponent(mpInstance._Store.prodStorageName), - Base64.encode(JSON.stringify(allLocalStorageProducts)) + const encodedKey = encodeURIComponent( + mpInstance._Store.prodStorageName + ); + const encodedValue = Base64.encode( + JSON.stringify(allLocalStorageProducts) ); + window.localStorage.setItem(encodedKey, encodedValue); } catch (e) { mpInstance.Logger.error( 'Error with setting products on localStorage.' @@ -894,6 +916,9 @@ export default function _Persistence(mpInstance) { }; this.getCartProducts = function(mpid) { + if (mpInstance._Store.getPrivacyFlag('Products')) { + return []; + } var allCartProducts, cartProductsString = localStorage.getItem( mpInstance._Store.prodStorageName @@ -913,7 +938,10 @@ export default function _Persistence(mpInstance) { }; this.setCartProducts = function(allProducts) { - if (!mpInstance._Store.isLocalStorageAvailable) { + if ( + !mpInstance._Store.isLocalStorageAvailable || + mpInstance._Store.getPrivacyFlag('Products') + ) { return; } diff --git a/test/jest/persistence.products.spec.ts b/test/jest/persistence.products.spec.ts new file mode 100644 index 000000000..ddeba7b58 --- /dev/null +++ b/test/jest/persistence.products.spec.ts @@ -0,0 +1,34 @@ +import { + mParticle, + MPConfig, + testMPID, + } from '../src/config/constants'; + import { Product } from '@mparticle/web-sdk'; + + describe('Products Persistence', () => { + let mpInstance = mParticle.getInstance(); + beforeEach(() => { + mParticle._resetForTests(MPConfig); + mpInstance._Persistence.resetPersistence(); + }); + + it('should save products to localStorage when noTargeting is false by default', () => { + const product: Partial = { Name: 'iphone', Sku: 'iphonesku', Price: 599, Quantity: 1 }; + mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } } as unknown as Product[]); + expect(mpInstance._Persistence.getCartProducts(testMPID).length).toBe(1); + }); + + it('should NOT save products to localStorage when noTargeting is true', () => { + mpInstance._Store.setNoTargeting(true); + const product: Partial = { Name: 'iphone', Sku: 'iphonesku', Price: 599, Quantity: 1 }; + mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } } as unknown as Product[]); + expect(mpInstance._Persistence.getCartProducts(testMPID).length).toBe(0); + }); + + it('should save products to localStorage when noTargeting is false', () => { + mpInstance._Store.setNoTargeting(false); + const product: Partial = { Name: 'iphone', Sku: 'iphonesku', Price: 599, Quantity: 1 }; + mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } } as unknown as Product[]); + expect(mpInstance._Persistence.getCartProducts(testMPID).length).toBe(1); + }); + }); \ No newline at end of file diff --git a/test/src/tests-persistence.ts b/test/src/tests-persistence.ts index 424f4d616..06133277c 100644 --- a/test/src/tests-persistence.ts +++ b/test/src/tests-persistence.ts @@ -1661,6 +1661,53 @@ describe('persistence', () => { parsedProductsAfter['testMPID'].cp.length.should.equal(0); }); + describe('products persistence with noTargeting privacy flag', () => { + beforeEach(() => { + mParticle._resetForTests(MPConfig); + }); + + it('should NOT save products to LS when noTargeting is true', async () => { + mParticle.config.launcherOptions = { noTargeting: true }; + + mParticle.init(apiKey, mParticle.config); + await waitForCondition(hasIdentifyReturned); + const localStorageProducts = localStorage.getItem(LocalStorageProductsV4WithWorkSpaceName); + expect(localStorageProducts).to.not.be.ok; + }); + + it('should save products to LS when noTargeting is false', async () => { + mParticle.config.launcherOptions = { noTargeting: false }; + + mParticle.init(apiKey, mParticle.config); + await waitForCondition(hasIdentifyReturned); + const iphone = mParticle.eCommerce.createProduct( + 'iphone', + 'iphonesku', + 599, + 1 + ); + mParticle.eCommerce.Cart.add(iphone, true); + + const localStorageProducts = localStorage.getItem(LocalStorageProductsV4WithWorkSpaceName); + expect(localStorageProducts).to.be.ok; + }); + + it('should save products to LS when noTargeting is false by default', async () => { + mParticle.init(apiKey, mParticle.config); + await waitForCondition(hasIdentifyReturned); + const iphone = mParticle.eCommerce.createProduct( + 'iphone', + 'iphonesku', + 599, + 1 + ); + mParticle.eCommerce.Cart.add(iphone, true); + + const localStorageProducts = localStorage.getItem(LocalStorageProductsV4WithWorkSpaceName); + expect(localStorageProducts).to.be.ok; + }); + }); + it('should only set setFirstSeenTime() once', async () => { const cookies = JSON.stringify({ gs: {