Skip to content

feat: disable product cookie when no targeting is true#1071

Closed
jaissica12 wants to merge 11 commits into
feat/SDKE-91-disable-session-cookie-localStorage-when-noFunctional-is-setfrom
feat/SDKE-92-disable-product-cookie-when-noTargeting-is-true
Closed

feat: disable product cookie when no targeting is true#1071
jaissica12 wants to merge 11 commits into
feat/SDKE-91-disable-session-cookie-localStorage-when-noFunctional-is-setfrom
feat/SDKE-92-disable-product-cookie-when-noTargeting-is-true

Conversation

@jaissica12

Copy link
Copy Markdown
Contributor

Instructions

  1. PR target branch should be against development
  2. PR title name should follow this format: https://github.com/mParticle/mparticle-workflows/blob/main/.github/workflows/pr-title-check.yml
  3. PR branch prefix should follow this format: https://github.com/mParticle/mparticle-workflows/blob/main/.github/workflows/pr-branch-check-name.yml

Summary

  • Updated persistence logic for products local storage:

    • Read: not read/consumed when noTargeting is true
    • Create: not created when noTargeting is true
    • Update: not updated when noTargeting is true; any existing products storage is also not removed
  • Added jest tests and integration tests

Testing Plan

  • Was this tested locally? If not, explain why.
  • {explain how this has been tested, and what, if any, additional testing should be done}

Reference Issue (For mParticle employees only. Ignore if you are an outside contributor)

Comment thread test/jest/persistence.spec.ts Outdated

it('should update Products localStorage when noTargeting is false by default', () => {
const product = { Name: 'iphone', Sku: 'iphonesku', Price: 599, Quantity: 1 };
mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } } as any);

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
mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } } as any);
mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } });

Comment thread test/jest/persistence.spec.ts Outdated
it('should NOT update Products localStorage when noTargeting is true', () => {
mpInstance._Store.setNoTargeting(true);
const product = { Name: 'iphone', Sku: 'iphonesku', Price: 599, Quantity: 1 };
mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } } as any);

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
mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } } as any);
mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } });

Comment thread test/jest/persistence.spec.ts Outdated
it('should update Products localStorage when noTargeting is false', () => {
mpInstance._Store.setNoTargeting(false);
const product = { Name: 'iphone', Sku: 'iphonesku', Price: 599, Quantity: 1 };
mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } } as any);

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
mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } } as any);
mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } });

Comment thread test/jest/persistence.spec.ts Outdated
Comment thread src/persistence.js
Comment thread src/persistence.js Outdated
this.setCartProducts = function(allProducts) {
if (!mpInstance._Store.isLocalStorageAvailable) {
if (
!mpInstance._Store.isLocalStorageAvailable &&

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should be OR, not AND. If local storage isn't available, or if getNoTargeting returns true, then don't set the cart products

Suggested change
!mpInstance._Store.isLocalStorageAvailable &&
!mpInstance._Store.isLocalStorageAvailable || mpInstance._Store.getNoTargeting

Comment thread test/jest/persistence.spec.ts Outdated
mParticle._resetForTests(MPConfig);
});

it('should update Products localStorage when noTargeting is false by default', () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
it('should update Products localStorage when noTargeting is false by default', () => {
it('should save products to localStorage when noTargeting is false by default', () => {

Comment thread test/jest/persistence.spec.ts Outdated
expect(mpInstance._Persistence.getCartProducts(testMPID).length).toBe(1);
});

it('should NOT update Products localStorage when noTargeting is true', () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
it('should NOT update Products localStorage when noTargeting is true', () => {
it('should NOT save products to localStorage when noTargeting is true', () => {

Comment thread test/jest/persistence.spec.ts Outdated
expect(mpInstance._Persistence.getCartProducts(testMPID)).toEqual([]);
});

it('should update Products localStorage when noTargeting is false', () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
it('should update Products localStorage when noTargeting is false', () => {
it('should save products to localStorage when noTargeting is false', () => {

Comment thread test/src/tests-persistence.ts Outdated
});

it('should not save products LS when noTargeting is true', async () => {
mParticle.config.noTargeting = true;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm surprised this is working.

Per the docs, this should be:

Suggested change
mParticle.config.noTargeting = true;
mParticle.config.launcherOptions = {noTargeting: true};

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@rmi22186 Currently noFunctional / noTargeting is only read from top‑level mParticle.config during init, not from config.launcherOptions that is why mParticle.config.noTargeting = true; works. To use mParticle.config.launcherOptions = {noTargeting: true}; we need to update store to source privacy flags from config.launcherOptions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Now that you have updated the noTargeting and noFunctional to pull from config.launcherOptions, this will need to be updated

Comment thread test/src/tests-persistence.ts Outdated
mParticle._resetForTests(MPConfig);
});

it('should not save products LS when noTargeting is true', async () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
it('should not save products LS when noTargeting is true', async () => {
it('should not save products to LS when noTargeting is true', async () => {

Comment thread test/src/tests-persistence.ts Outdated
expect(localStorageProducts).to.not.be.ok;
});

it('should save products LS when noTargeting is false', async () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
it('should save products LS when noTargeting is false', async () => {
it('should save products to LS when noTargeting is false', async () => {

Comment thread test/src/tests-persistence.ts Outdated
});

it('should save products LS when noTargeting is false', async () => {
mParticle.config.noTargeting = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
mParticle.config.noTargeting = false;
mParticle.config.launcherOptions = {noTargeting: false};

Comment thread test/src/tests-persistence.ts Outdated
expect(localStorageProducts).to.be.ok;
});

it('should save products LS when noTargeting is false by default', async () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
it('should save products LS when noTargeting is false by default', async () => {
it('should save products to LS when noTargeting is false by default', async () => {

@rmi22186 rmi22186 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

minor nits. also needs to be rebased against #1063 and logic need to be updated using mpInstance._Store.getPrivacyFlag

@rmi22186 rmi22186 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There are changes to persistnece.js in both
https://github.com/mParticle/mparticle-web-sdk/pull/1070/files and
https://github.com/mParticle/mparticle-web-sdk/pull/1071/files

I feel like it's going to create a merging/rebasing nightmare once 1070 is merged, or 1071 is merged first. I think you need to either combine 1070 and 1071 into a single PR, or use 1070 as what you are PR-ing into instead of development for this branch.

@jaissica12 jaissica12 changed the base branch from development to feat/SDKE-91-disable-session-cookie-localStorage-when-noFunctional-is-set September 25, 2025 12:52
@jaissica12

Copy link
Copy Markdown
Contributor Author

There are changes to persistnece.js in both https://github.com/mParticle/mparticle-web-sdk/pull/1070/files and https://github.com/mParticle/mparticle-web-sdk/pull/1071/files

I feel like it's going to create a merging/rebasing nightmare once 1070 is merged, or 1071 is merged first. I think you need to either combine 1070 and 1071 into a single PR, or use 1070 as what you are PR-ing into instead of development for this branch.

I agree! I have changed the target for PR to 1070. Once this PR is approved I'll merge it into 1070 and then:

  1. Clean up persistence logic wherever its needed.
  2. Merge the tests for Persistence into one file (persistence.spec.ts)

@jaissica12 jaissica12 requested a review from rmi22186 September 25, 2025 21:12
Comment thread src/persistence.js Outdated
Comment on lines +361 to +373
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))
);
if (!mpInstance._Store.getPrivacyFlag('Products')) {
window.localStorage.setItem(
encodeURIComponent(mpInstance._Store.prodStorageName),
Base64.encode(JSON.stringify(allLocalStorageProducts))
);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is the if check for 368 necessary here? Since you have 361-363 already returning based on the Products privacy flag, I don't think you need to check for the inverse of 361 on line 368.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree, its not needed here since we're already returning at line 362

@rmi22186 rmi22186 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

minor nits

Comment thread src/persistence.js Outdated
Comment on lines +369 to +372
window.localStorage.setItem(
encodeURIComponent(mpInstance._Store.prodStorageName),
Base64.encode(JSON.stringify(allLocalStorageProducts))
);

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.

I would also clean up the original code a bit so that i's more readable:

Suggested change
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);

Comment thread test/jest/persistence.products.spec.ts Outdated
Comment on lines +16 to +18
const product = { 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);

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.

I think instead of trying to coerce the Type, let's see if we can use a Partial so we can maintain type safety.

Suggested change
const product = { 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);
const product: Partial<Product> = { Name: 'iphone', Sku: 'iphonesku', Price: 599, Quantity: 1 };
mpInstance._Persistence.setCartProducts({ [testMPID]: { cp: [product] } });
expect(mpInstance._Persistence.getCartProducts(testMPID).length).toBe(1);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@alexs-mparticle I’ve incorporated Partial<Product> for the item, but I’m still hitting the TypeScript error since setCartProducts is typed as Product[] while the runtime path expects a per‑MPID map. That’s why I had to coerce the call to match the actual shape earlier as well. If there’s a better approach or a preferred workaround to avoid the cast while keeping the test on the real write path, please advise and I’ll update.

@sonarqubecloud

Copy link
Copy Markdown

@jaissica12 jaissica12 closed this Sep 26, 2025
@jaissica12

Copy link
Copy Markdown
Contributor Author

Closing this PR since we are removing setCartProducts and getCartProducts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants