Skip to content
This repository was archived by the owner on Aug 28, 2026. It is now read-only.

Commit 2e683d6

Browse files
authored
ENG-3648: Fix FidesJS banner resurfacing on non-applicable notices (#8137)
1 parent dbb927f commit 2e683d6

3 files changed

Lines changed: 74 additions & 2 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
type: Fixed
2+
description: Fixed FidesJS banner resurfacing when a served notice was previously stored as non-applicable
3+
pr: 8137
4+
labels: []

clients/fides-js/src/components/notices/NoticeOverlay.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
isConsentOverride,
2828
} from "../../lib/consent-utils";
2929
import { resolveConsentValue } from "../../lib/consent-value";
30-
import { consentCookieObjHasSomeConsentSet } from "../../lib/cookie";
3130
import {
3231
FidesEventDetailsPreference,
3332
FidesEventDetailsServingComponent,
@@ -372,7 +371,17 @@ const NoticeOverlay = () => {
372371
);
373372

374373
const handleDismiss = useCallback(() => {
375-
if (!consentCookieObjHasSomeConsentSet(parsedCookie?.consent)) {
374+
// Skip the dismiss-update only when every currently-applicable notice
375+
// already has a recorded preference in the saved cookie. Otherwise a
376+
// newly-applicable notice (e.g. one that was non-applicable in a prior
377+
// region and is now served) would never get written to the consent map
378+
// on dismiss, causing the banner to resurface on every reload until the
379+
// user explicitly saves their preferences.
380+
const allApplicableNoticesHavePreference =
381+
experience.privacy_notices?.every(
382+
(notice) => parsedCookie?.consent?.[notice.notice_key] !== undefined,
383+
) ?? true;
384+
if (!allApplicableNoticesHavePreference) {
376385
handleUpdatePreferences(
377386
ConsentMethod.DISMISS,
378387
getEnabledNoticeKeys(cookie?.consent),
@@ -381,6 +390,7 @@ const NoticeOverlay = () => {
381390
}, [
382391
handleUpdatePreferences,
383392
getEnabledNoticeKeys,
393+
experience.privacy_notices,
384394
parsedCookie?.consent,
385395
cookie?.consent,
386396
]);

clients/privacy-center/cypress/e2e/fides-js/banner-overlay-dismissal.cy.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { CONSENT_COOKIE_NAME, ConsentMethod, FidesCookie } from "fides-js";
22

3+
import { mockCookie } from "../../support/mocks";
34
import { stubConfig, stubTCFExperience } from "../../support/stubs";
45

56
describe("Banner and modal dismissal", () => {
@@ -245,4 +246,61 @@ describe("Banner and modal dismissal", () => {
245246
});
246247
},
247248
);
249+
250+
// When the saved cookie has prior decisions for some notices but lists a
251+
// currently-served notice in `non_applicable_notice_keys` (i.e. that notice
252+
// was non-applicable in a prior region), dismissing the banner must record
253+
// a default preference for the now-applicable notice. Otherwise the banner
254+
// would resurface on every reload until the user explicitly saved.
255+
describe("when a served notice has no recorded preference but is in non_applicable_notice_keys", () => {
256+
beforeEach(() => {
257+
cy.fixture("consent/fidesjs_options_banner_modal.json").then((config) => {
258+
const experienceItem = config.experience;
259+
experienceItem.experience_config.dismissable = true;
260+
261+
// Seed a cookie with consent for an unrelated notice and "advertising"
262+
// recorded as previously non-applicable. The current experience serves
263+
// "advertising" as applicable, so the banner should resurface once.
264+
const cookie = mockCookie({
265+
consent: { essential: true },
266+
fides_meta: {
267+
version: "0.9.0",
268+
createdAt: "2024-01-01T12:00:00.000Z",
269+
updatedAt: "2024-01-01T12:00:00.000Z",
270+
consentMethod: ConsentMethod.ACCEPT,
271+
},
272+
non_applicable_notice_keys: ["advertising"],
273+
});
274+
cy.setCookie(CONSENT_COOKIE_NAME, JSON.stringify(cookie));
275+
276+
stubConfig({
277+
options: { tcfEnabled: false },
278+
experience: experienceItem,
279+
});
280+
});
281+
});
282+
283+
it("records a default preference for the served notice on dismiss and stops resurfacing", () => {
284+
cy.get("#fides-banner").should("be.visible");
285+
cy.get("#fides-banner .fides-close-button").click();
286+
cy.get("#fides-banner").should("not.be.visible");
287+
288+
cy.waitUntilCookieExists(CONSENT_COOKIE_NAME).then(() => {
289+
cy.getCookie(CONSENT_COOKIE_NAME).then((cookie) => {
290+
const fidesCookie: FidesCookie = JSON.parse(
291+
decodeURIComponent(cookie!.value),
292+
);
293+
// The dismiss flow should have recorded a default value for the
294+
// newly-applicable notice while preserving the existing decision.
295+
expect(fidesCookie.consent).to.have.property("advertising");
296+
expect(fidesCookie.fides_meta.consentMethod).to.eql(
297+
ConsentMethod.DISMISS,
298+
);
299+
});
300+
});
301+
302+
cy.reload();
303+
cy.get("#fides-banner").should("not.be.visible");
304+
});
305+
});
248306
});

0 commit comments

Comments
 (0)