From f5c7da68e35ca07715de99198628b2b0b85df987 Mon Sep 17 00:00:00 2001 From: Jason Gill Date: Wed, 5 Jun 2024 15:17:59 -0600 Subject: [PATCH 1/3] include tests for signal status when TCF disabled --- .../privacy-center/cypress/e2e/consent-banner-gpp.cy.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clients/privacy-center/cypress/e2e/consent-banner-gpp.cy.ts b/clients/privacy-center/cypress/e2e/consent-banner-gpp.cy.ts index 345b20786c..f424d0a5be 100644 --- a/clients/privacy-center/cypress/e2e/consent-banner-gpp.cy.ts +++ b/clients/privacy-center/cypress/e2e/consent-banner-gpp.cy.ts @@ -383,6 +383,7 @@ describe("Fides-js GPP extension", () => { .its("lastCall.args") .then(([data, success]) => { expect(success).to.eql(true); + // because TCF is disabled, status can always be "ready" expect(data.signalStatus).to.eql("ready"); }); }); @@ -535,6 +536,8 @@ describe("Fides-js GPP extension", () => { // Opt in string expect(data.pingData.applicableSections).to.eql([8]); expect(data.pingData.gppString).to.eql("DBABBg~BUoAAABY.QA"); + // because TCF is disabled, status can always be "ready" + expect(data.pingData.signalStatus).to.eql("ready"); }); }); }); @@ -564,6 +567,7 @@ describe("Fides-js GPP extension", () => { .its("lastCall.args") .then(([data, success]) => { expect(success).to.eql(true); + // because TCF is disabled, status can always be "ready" expect(data.signalStatus).to.eql("ready"); expect(data.applicableSections).to.eql([-1]); }); @@ -581,6 +585,7 @@ describe("Fides-js GPP extension", () => { const [data, success] = args[2]; expect(success).to.eql(true); expect(data.pingData.applicableSections).to.eql([-1]); + expect(data.pingData.signalStatus).to.eql("ready"); }); }); @@ -595,6 +600,7 @@ describe("Fides-js GPP extension", () => { const [data, success] = args[2]; expect(success).to.eql(true); expect(data.pingData.applicableSections).to.eql([-1]); + expect(data.pingData.signalStatus).to.eql("ready"); }); }); @@ -624,6 +630,8 @@ describe("Fides-js GPP extension", () => { // Opt in string expect(data.pingData.applicableSections).to.eql([-1]); expect(data.pingData.gppString).to.eql("DBAA"); + // because TCF is disabled, status can always be "ready" + expect(data.pingData.signalStatus).to.eql("ready"); }); }); }); From 5a8ec5de1b8852db23f7d718abb43a2880bb1545 Mon Sep 17 00:00:00 2001 From: Jason Gill Date: Wed, 5 Jun 2024 15:19:03 -0600 Subject: [PATCH 2/3] change signalStatus to "not ready" in appropriate scenarios --- clients/fides-js/src/fides-ext-gpp.ts | 18 +++++++---- .../cypress/e2e/consent-banner-gpp.cy.ts | 30 +++++++++---------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/clients/fides-js/src/fides-ext-gpp.ts b/clients/fides-js/src/fides-ext-gpp.ts index f65de11cfe..d8b09b9c93 100644 --- a/clients/fides-js/src/fides-ext-gpp.ts +++ b/clients/fides-js/src/fides-ext-gpp.ts @@ -133,18 +133,19 @@ const initializeGppCmpApi = () => { makeStub(); const cmpApi = new CmpApi(ETHYCA_CMP_ID, CMP_VERSION); cmpApi.setCmpStatus(CmpStatus.LOADED); - // If consent does not need to be resurfaced, then we can set the signal to Ready here window.addEventListener("FidesInitialized", (event) => { // TODO (PROD-1439): re-evaluate if GPP is "cheating" accessing window.Fides instead of using the event details only - const { experience, saved_consent: savedConsent } = window.Fides; + const { experience, saved_consent: savedConsent, options } = window.Fides; + const isTcfEnabled = options.tcfEnabled; cmpApi.setSupportedAPIs(getSupportedApis()); // Set status to ready immediately upon initialization, if either: // A. Consent should not be resurfaced - // B. User has no prefs and has all opt-in notices + // B. User has no prefs and has all opt-in notices and TCF is disabled if ( isPrivacyExperience(experience) && (!shouldResurfaceConsent(experience, event.detail, savedConsent) || - (allNoticesAreDefaultOptIn(experience.privacy_notices) && + (!isTcfEnabled && + allNoticesAreDefaultOptIn(experience.privacy_notices) && !userHasExistingPrefs( savedConsent, event.detail.fides_string, @@ -176,10 +177,12 @@ const initializeGppCmpApi = () => { window.addEventListener("FidesUIShown", (event) => { // Set US GPP notice fields - const { experience, saved_consent: savedConsent } = window.Fides; + const { experience, saved_consent: savedConsent, options } = window.Fides; + const isTcfEnabled = options.tcfEnabled; if (isPrivacyExperience(experience)) { - // set signal status to ready only for users with no existing prefs and if notices are all opt-in by default + // set signal status to ready only for users with no existing prefs and if notices are all opt-in by default and TCF is disabled if ( + !isTcfEnabled && allNoticesAreDefaultOptIn(experience.privacy_notices) && !userHasExistingPrefs( savedConsent, @@ -198,6 +201,9 @@ const initializeGppCmpApi = () => { }); if (sectionsChanged.length) { cmpApi.setApplicableSections(sectionsChanged.map((s) => s.id)); + sectionsChanged.forEach((section) => { + cmpApi.fireSectionChange(section.name); + }); } } }); diff --git a/clients/privacy-center/cypress/e2e/consent-banner-gpp.cy.ts b/clients/privacy-center/cypress/e2e/consent-banner-gpp.cy.ts index f424d0a5be..621ec0befd 100644 --- a/clients/privacy-center/cypress/e2e/consent-banner-gpp.cy.ts +++ b/clients/privacy-center/cypress/e2e/consent-banner-gpp.cy.ts @@ -93,7 +93,7 @@ describe("Fides-js GPP extension", () => { .its("lastCall.args") .then(([data, success]) => { expect(success).to.eql(true); - expect(data.signalStatus).to.eql("ready"); + expect(data.signalStatus).to.eql("not ready"); }); }); }); @@ -114,8 +114,8 @@ describe("Fides-js GPP extension", () => { it("fires appropriate gpp events for first time user", () => { cy.waitUntilFidesInitialized().then(() => { cy.get("@FidesUIShown").should("have.been.calledOnce"); - // TODO(PROD#1439): Because the stub is too late right now, we can't listen for events - // 3 and 4 yet. + // TODO(PROD#1439): Because the stub is too late right now, we can't listen for events 3 and 4 yet. + cy.window().then((win) => { win.__gpp("addEventListener", cy.stub().as("gppListener")); }); @@ -128,7 +128,7 @@ describe("Fides-js GPP extension", () => { expect(data.eventName).to.eql("listenerRegistered"); const { cmpDisplayStatus, signalStatus, gppString } = data.pingData; expect(cmpDisplayStatus).to.eql("visible"); - expect(signalStatus).to.eql("ready"); + expect(signalStatus).to.eql("not ready"); expect(gppString).to.eql("DBAA"); // empty string, header only }); @@ -193,8 +193,8 @@ describe("Fides-js GPP extension", () => { cy.waitUntilFidesInitialized().then(() => { cy.get("@FidesUIShown").should("not.have.been.called"); - // TODO(PROD#1439): Because the stub is too late right now, we can't listen for events - // 3 and 4 yet. + // TODO(PROD#1439): Because the stub is too late right now, we can't listen for events 3 and 4 yet. + cy.window().then((win) => { win.__gpp("addEventListener", cy.stub().as("gppListener")); }); @@ -228,6 +228,7 @@ describe("Fides-js GPP extension", () => { .its("args") .then((args) => { expect(args.length).to.eql(3); + // when modal opens, the signal status should be changed back to "not ready" const expected = [ { eventName: "signalStatus", data: "not ready" }, { eventName: "cmpDisplayStatus", data: "visible" }, @@ -277,8 +278,10 @@ describe("Fides-js GPP extension", () => { * 7. signalStatus = not ready */ it("can handle returning user closing the modal", () => { + const tcString = "CPziCYAPziCYAGXABBENATEIAACAAAAAAAAAABEAAAAA"; const cookie = mockCookie({ tcf_version_hash: TCF_VERSION_HASH, + fides_string: tcString, }); cy.setCookie(CONSENT_COOKIE_NAME, JSON.stringify(cookie)); cy.fixture("consent/experience_tcf.json").then((experience) => { @@ -296,9 +299,11 @@ describe("Fides-js GPP extension", () => { }); cy.get("#fides-modal-link").click(); cy.get(".fides-modal-content .fides-close-button").click(); + + // when modal opens, the signal status should be changed back to "not ready" const expected = [ { eventName: "listenerRegistered", data: true }, - { eventName: "signalStatus", data: "ready" }, + { eventName: "signalStatus", data: "not ready" }, { eventName: "cmpDisplayStatus", data: "visible" }, { eventName: "cmpDisplayStatus", data: "hidden" }, { eventName: "signalStatus", data: "ready" }, @@ -349,14 +354,9 @@ describe("Fides-js GPP extension", () => { expect(success).to.eql(true); expect(data.eventName).to.eql("cmpDisplayStatus"); expect(data.data).to.eql("visible"); - const { - signalStatus, - gppString, - applicableSections, - supportedAPIs, - } = data.pingData; - expect(signalStatus).to.eql("ready"); - expect(applicableSections).to.eql([-1]); + const { signalStatus, gppString, supportedAPIs } = data.pingData; + // when modal opens, the signal status should be changed back to "not ready" + expect(signalStatus).to.eql("not ready"); expect(supportedAPIs).to.eql([]); expect(gppString).to.eql("DBAA"); }); From 0828b28809126cb058dae43efb62cf7e8e001238 Mon Sep 17 00:00:00 2001 From: Jason Gill Date: Wed, 5 Jun 2024 15:36:46 -0600 Subject: [PATCH 3/3] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10ad08cfde..8a3344001d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ The types of changes are: - Fixed an issue where language form field error message was not displaying properly [#4942](https://github.com/ethyca/fides/pull/4942) - Fixed an issue where the consent cookie could not be set on multi-level root domain (e.g. co.uk, co.jp) [#4935](https://github.com/ethyca/fides/pull/4935) - Fixed an issue where the unique device ID was not being retained when Fides.js was reinitialized [#4947](https://github.com/ethyca/fides/pull/4947) +- Fixed an issue where the GPP signal status was prematurely set to `ready` in some scenarios [#4957](https://github.com/ethyca/fides/pull/4957) ## [2.37.0](https://github.com/ethyca/fides/compare/2.36.0...2.37.0)