Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Fides.shouldShouldShowExperience() to return false for modal-only experiences #5281

Merged
merged 8 commits into from
Sep 12, 2024

Conversation

NevilleS
Copy link
Contributor

@NevilleS NevilleS commented Sep 12, 2024

Closes PROD-2763

Description Of Changes

This adds a tiny bit of logic to the FidesJS SDK function shouldShowExperience() to fix a bug where we would return true confusingly for modal-only experiences that would not automatically show an experience to prompt for consent. The expected behaviour of this function is to return true only when the user should be prompted via a consent banner.

The bulk of this PR adds a thorough set of E2E tests to ensure that this SDK function is tested over all the FidesJS experience types, with & without saved consent.

Code Changes

  • Fix shouldResurfaceConsent helper to always return false for modal-only experiences
  • Fix unrelated bug in updateExperienceFromCookieConsentNotices to correctly handle prefetched experiences without any notices (e.g. an empty experience)
  • Add automated E2E tests for modal, banner+modal, tcf, and empty experiences
  • Remove lingering references to the show_banner field that was removed

Steps to Confirm

  • Load a default US Modal experience in Cookie House and confirm that Fides.shouldShowExperience() returns false as expected
  • Load a default EEA Banner + Modal experience in Cookie House and confirm that Fides.shouldShowExperience() returns true as expected and the banner is shown
  • Opt-in or opt-out of the EEA Banner, refresh the page, and confirm that Fides.shouldShowExperience() returns false as expected and no banner is shown
  • Load a default TCF Overlay experience in Cookie House and confirm that Fides.shouldShowExperience() returns true as expected and the banner is shown
  • Opt-in or opt-out of the TCF Overlay, refresh the page, and confirm that Fides.shouldShowExperience() returns false as expected and no banner is shown

Pre-Merge Checklist

  • All CI Pipelines Succeeded
  • Documentation:
    • documentation complete, PR opened in fidesdocs
    • documentation issue created in fidesdocs
    • if there are any new client scopes created as part of the pull request, remember to update public-facing documentation that references our scope registry
  • Issue Requirements are Met
  • Relevant Follow-Up Issues Created
  • Update CHANGELOG.md
  • For API changes, the Postman collection has been updated
  • If there are any database migrations:
    • Ensure that your downrev is up to date with the latest revision on main
    • Ensure that your downgrade() migration is correct and works
      • If a downgrade migration is not possible for this change, please call this out in the PR description!

Copy link

vercel bot commented Sep 12, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
fides-plus-nightly ⬜️ Ignored (Inspect) Visit Preview Sep 12, 2024 0:17am

Copy link

cypress bot commented Sep 12, 2024

fides    Run #9922

Run Properties:  status check passed Passed #9922  •  git commit 6a797ccd74 ℹ️: Merge 2fb7e21c75c8762ef267e8e3d74df2d83d713474 into aa37211d487f7ec3a5b38b58f923...
Project fides
Branch Review refs/pull/5281/merge
Run status status check passed Passed #9922
Run duration 00m 38s
Commit git commit 6a797ccd74 ℹ️: Merge 2fb7e21c75c8762ef267e8e3d74df2d83d713474 into aa37211d487f7ec3a5b38b58f923...
Committer Neville Samuell
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 4
⚠️ You've recorded test results over your free plan limit.
Upgrade your plan to view test results.
View all changes introduced in this branch ↗︎

Copy link
Contributor Author

@NevilleS NevilleS left a comment

Choose a reason for hiding this comment

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

Couple guiding comments!

Comment on lines +248 to +251
// Never surface consent for modal-only experiences
if (experience.experience_config?.component === ComponentType.MODAL) {
return false;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the fix - it's effectively a one-line adjustment to make this utility shouldResurfaceConsent() behave as expected when using a modal-only experience. This method is called directly by Fides.shouldShowExperience() to determine whether or not the experience will be shown to the user automatically during the init() sequence.

(the rest of the PR is E2E tests for all the experience types)

Copy link
Contributor

Choose a reason for hiding this comment

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

Great. Thanks for adding the e2e tests!

Comment on lines +263 to +267
// If the given experience has no notices, return immediately and do not mutate
// the experience object in any way
if (!experience.privacy_notices) {
return experience;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was an unrelated, but subtle bug. I found that if there was a saved consent cookie and a prefetched empty experience (e.g. experience: {}), this function would get called and edit the experience to become { privacy_notices: undefined }, which is unexpected by the rest of the code base.

The impact of this is probably zero-to-none, it'd be a really extreme edge case where a user (1) visits a website and gets a valid experience, (2) saves their consent preference, (3) visits the website again from a different location without an experience, (4) this method causes the experience to appear non-empty but without notices, (5) client will then refetch the experience client-side, slowing down the init.

Just fixing this up.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks. It's definitely not a common use case, but I can see how someone travelling or VPNing might get into this state.

Comment on lines +23 to +27
{
fixture: "experience_modal.json",
savedConsent: false,
shouldShowExperience: false,
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was the failing case- without the fix to shouldResurfaceConsent, this test fails because shouldShowExperience returns true unexpectedly.

expiredTcfVersionHash,
shouldShowExperience,
}) => {
describe(`when rendering ${fixture} and saved consent ${savedConsent ? "exists" : "does not exist"} ${expiredTcfVersionHash ? "(with expired tcf_version_hash)" : ""}`, () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks to the parameterized tests above, this'll exercise 9 different combinations of experiences + saved consent.

Comment on lines +11 to +20
interface TestCaseOptions {
fixture:
| "experience_modal.json"
| "experience_banner_modal.json"
| "experience_tcf_minimal.json"
| "experience_none.json";
savedConsent: boolean;
expiredTcfVersionHash?: boolean;
shouldShowExperience: boolean;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test fixtures modify three inputs:

  1. fixture: the type of experience to test
  2. savedConsent: whether or not the user has a previously saved consent cookie
  3. expiredTcfVersionHash: special case for TCF, whether the user should have a previously saved consent cookie but with an expired version hash (that doesn't match the latest experience)

It then asserts to see if Fides.shouldShowExperience() returns the expected result of shouldShowExperience in the param.

@@ -10,9 +10,6 @@ describe("Fides.showModal", () => {
options: {
isOverlayEnabled: true,
},
experience: {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was a red herring and didn't affect these tests, removing show_banner entirely as it's not returned by the API anymore.

"auto_detect_language": true,
"disabled": false,
"id": "pri_exp-modal-000",
"component": "modal",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added this fixture to ensure we had a mock API response for the US-only modal component type.

@@ -0,0 +1,6 @@
{
"items": [],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added this fixture to ensure we had a mock response for an empty experience, not matching any location.

Copy link
Contributor

@lucanovera lucanovera left a comment

Choose a reason for hiding this comment

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

Tested through each use case and found the shouldShowExperience returned value to be correct each time. Found no issues with the code. Approved!

Comment on lines +248 to +251
// Never surface consent for modal-only experiences
if (experience.experience_config?.component === ComponentType.MODAL) {
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Great. Thanks for adding the e2e tests!

Comment on lines +263 to +267
// If the given experience has no notices, return immediately and do not mutate
// the experience object in any way
if (!experience.privacy_notices) {
return experience;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks. It's definitely not a common use case, but I can see how someone travelling or VPNing might get into this state.

@NevilleS NevilleS merged commit 47934f2 into main Sep 12, 2024
13 checks passed
@NevilleS NevilleS deleted the PROD-2763-fix-should-show-experience branch September 12, 2024 18:52
NevilleS added a commit that referenced this pull request Sep 12, 2024
Copy link

cypress bot commented Sep 12, 2024

fides    Run #9933

Run Properties:  status check passed Passed #9933  •  git commit 47934f2610: Fix Fides.shouldShouldShowExperience() to return false for modal-only experience...
Project fides
Branch Review main
Run status status check passed Passed #9933
Run duration 00m 38s
Commit git commit 47934f2610: Fix Fides.shouldShouldShowExperience() to return false for modal-only experience...
Committer Neville Samuell
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 4
⚠️ You've recorded test results over your free plan limit.
Upgrade your plan to view test results.
View all changes introduced in this branch ↗︎

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.

2 participants