diff --git a/.changeset/popular-elephants-rush.md b/.changeset/popular-elephants-rush.md new file mode 100644 index 000000000..a043d30bd --- /dev/null +++ b/.changeset/popular-elephants-rush.md @@ -0,0 +1,5 @@ +--- +'@segment/analytics-consent-tools': patch +--- + +Change meaning of consent to 'user has consented ALL categories' diff --git a/packages/consent/consent-tools/src/domain/__tests__/create-wrapper.test.ts b/packages/consent/consent-tools/src/domain/__tests__/create-wrapper.test.ts index e2ed3f42f..3658023d2 100644 --- a/packages/consent/consent-tools/src/domain/__tests__/create-wrapper.test.ts +++ b/packages/consent/consent-tools/src/domain/__tests__/create-wrapper.test.ts @@ -368,11 +368,36 @@ describe(createWrapper, () => { ) }) - it('should allow integration if an integration has multiple categories, and user has multiple categories, but only consents to one', async () => { + it('should allow integration if it has one category and user has consented to that category', async () => { const mockCdnSettings = settingsBuilder .addActionDestinationSettings({ creationName: 'mockIntegration', - ...createConsentSettings(['Bar', 'Something else']), + ...createConsentSettings(['Foo']), + }) + .build() + + wrapTestAnalytics({ + shouldLoad: () => ({ Foo: true }), + }) + await analytics.load({ + ...DEFAULT_LOAD_SETTINGS, + cdnSettings: mockCdnSettings, + }) + expect(analyticsLoadSpy).toBeCalled() + const { updatedCDNSettings } = getAnalyticsLoadLastCall() + // remote plugins should be filtered based on consent settings + expect(updatedCDNSettings.remotePlugins).toContainEqual( + mockCdnSettings.remotePlugins?.find( + (p) => p.creationName === 'mockIntegration' + ) + ) + }) + + it('should allow integration if it has multiple categories and user consents to all of them.', async () => { + const mockCdnSettings = settingsBuilder + .addActionDestinationSettings({ + creationName: 'mockIntegration', + ...createConsentSettings(['Foo', 'Bar']), }) .build() @@ -386,18 +411,18 @@ describe(createWrapper, () => { expect(analyticsLoadSpy).toBeCalled() const { updatedCDNSettings } = getAnalyticsLoadLastCall() // remote plugins should be filtered based on consent settings - expect(updatedCDNSettings.remotePlugins).toEqual( - mockCdnSettings.remotePlugins?.filter( + expect(updatedCDNSettings.remotePlugins).toContainEqual( + mockCdnSettings.remotePlugins?.find( (p) => p.creationName === 'mockIntegration' ) ) }) - it('should allow integration if it has multiple consent categories but user has only consented to one category', async () => { + it('should disable integration if it has multiple categories but user has only consented to one', async () => { const mockCdnSettings = settingsBuilder .addActionDestinationSettings({ creationName: 'mockIntegration', - ...createConsentSettings(['Foo', 'Something else']), + ...createConsentSettings(['Foo', 'Bar']), }) .build() @@ -410,8 +435,8 @@ describe(createWrapper, () => { }) const { updatedCDNSettings } = getAnalyticsLoadLastCall() - expect(updatedCDNSettings.remotePlugins).toEqual( - mockCdnSettings.remotePlugins?.filter( + expect(updatedCDNSettings.remotePlugins).not.toContainEqual( + mockCdnSettings.remotePlugins?.find( (p) => p.creationName === 'mockIntegration' ) ) diff --git a/packages/consent/consent-tools/src/domain/create-wrapper.ts b/packages/consent/consent-tools/src/domain/create-wrapper.ts index 531af2113..dc11e137b 100644 --- a/packages/consent/consent-tools/src/domain/create-wrapper.ts +++ b/packages/consent/consent-tools/src/domain/create-wrapper.ts @@ -182,6 +182,7 @@ const omitDisabledRemotePlugins = ( return true } - const hasUserConsent = categories.some((c) => consentedCategories[c]) + // Enable if all of its consent categories are consented to + const hasUserConsent = categories.every((c) => consentedCategories[c]) return hasUserConsent }) diff --git a/packages/consent/consent-tools/src/types/settings.ts b/packages/consent/consent-tools/src/types/settings.ts index a2a2353c5..8f983195e 100644 --- a/packages/consent/consent-tools/src/types/settings.ts +++ b/packages/consent/consent-tools/src/types/settings.ts @@ -50,32 +50,14 @@ export interface CreateWrapperSettings { integrationCategoryMappings?: IntegrationCategoryMappings /** - * Predicate function to override default logic around whether or not to load an integration. - * @default - * ```ts - * // consent if user consents to at least one category defined in the integration - * (integrationCategories, categories, _info) => { - * if (!integrationCategories.length) return true - * return integrationCategories.some((c) => categories[c]) - * } - * ``` - * - * @example - - * ```ts - * (integrationCategories, categories, _info) => { - * // consent if user consents to _all_ categories defined in the integration - * if (!integrationCategories.length) return true - * return integrationCategories.every((c) => categories[c]) - * } - * ``` - * + * Predicate function to override default logic around whether or not to load an integration. By default, consent requires a user to have all categories enabled for a given integration. * @example * ```ts - * // count consent as usual, but always disable a particular plugin - * (integrationCategories, categories, { creationName }) => { + * // Always disable a particular plugin + * const shouldEnableIntegration = (integrationCategories, categories, { creationName }) => { * if (creationName === 'FullStory') return false * if (!integrationCategories.length) return true - * return integrationCategories.some((c) => categories[c]) + * return integrationCategories.every((c) => categories[c]) * } * ``` */