Skip to content

Commit 6789f9b

Browse files
authored
Only enable integration if _all_ consent categories are consented to. (#898)
1 parent 48ce3ec commit 6789f9b

File tree

4 files changed

+44
-31
lines changed

4 files changed

+44
-31
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@segment/analytics-consent-tools': patch
3+
---
4+
5+
Change meaning of consent to 'user has consented ALL categories'

packages/consent/consent-tools/src/domain/__tests__/create-wrapper.test.ts

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,36 @@ describe(createWrapper, () => {
368368
)
369369
})
370370

371-
it('should allow integration if an integration has multiple categories, and user has multiple categories, but only consents to one', async () => {
371+
it('should allow integration if it has one category and user has consented to that category', async () => {
372372
const mockCdnSettings = settingsBuilder
373373
.addActionDestinationSettings({
374374
creationName: 'mockIntegration',
375-
...createConsentSettings(['Bar', 'Something else']),
375+
...createConsentSettings(['Foo']),
376+
})
377+
.build()
378+
379+
wrapTestAnalytics({
380+
shouldLoad: () => ({ Foo: true }),
381+
})
382+
await analytics.load({
383+
...DEFAULT_LOAD_SETTINGS,
384+
cdnSettings: mockCdnSettings,
385+
})
386+
expect(analyticsLoadSpy).toBeCalled()
387+
const { updatedCDNSettings } = getAnalyticsLoadLastCall()
388+
// remote plugins should be filtered based on consent settings
389+
expect(updatedCDNSettings.remotePlugins).toContainEqual(
390+
mockCdnSettings.remotePlugins?.find(
391+
(p) => p.creationName === 'mockIntegration'
392+
)
393+
)
394+
})
395+
396+
it('should allow integration if it has multiple categories and user consents to all of them.', async () => {
397+
const mockCdnSettings = settingsBuilder
398+
.addActionDestinationSettings({
399+
creationName: 'mockIntegration',
400+
...createConsentSettings(['Foo', 'Bar']),
376401
})
377402
.build()
378403

@@ -386,18 +411,18 @@ describe(createWrapper, () => {
386411
expect(analyticsLoadSpy).toBeCalled()
387412
const { updatedCDNSettings } = getAnalyticsLoadLastCall()
388413
// remote plugins should be filtered based on consent settings
389-
expect(updatedCDNSettings.remotePlugins).toEqual(
390-
mockCdnSettings.remotePlugins?.filter(
414+
expect(updatedCDNSettings.remotePlugins).toContainEqual(
415+
mockCdnSettings.remotePlugins?.find(
391416
(p) => p.creationName === 'mockIntegration'
392417
)
393418
)
394419
})
395420

396-
it('should allow integration if it has multiple consent categories but user has only consented to one category', async () => {
421+
it('should disable integration if it has multiple categories but user has only consented to one', async () => {
397422
const mockCdnSettings = settingsBuilder
398423
.addActionDestinationSettings({
399424
creationName: 'mockIntegration',
400-
...createConsentSettings(['Foo', 'Something else']),
425+
...createConsentSettings(['Foo', 'Bar']),
401426
})
402427
.build()
403428

@@ -410,8 +435,8 @@ describe(createWrapper, () => {
410435
})
411436

412437
const { updatedCDNSettings } = getAnalyticsLoadLastCall()
413-
expect(updatedCDNSettings.remotePlugins).toEqual(
414-
mockCdnSettings.remotePlugins?.filter(
438+
expect(updatedCDNSettings.remotePlugins).not.toContainEqual(
439+
mockCdnSettings.remotePlugins?.find(
415440
(p) => p.creationName === 'mockIntegration'
416441
)
417442
)

packages/consent/consent-tools/src/domain/create-wrapper.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ const omitDisabledRemotePlugins = (
182182
return true
183183
}
184184

185-
const hasUserConsent = categories.some((c) => consentedCategories[c])
185+
// Enable if all of its consent categories are consented to
186+
const hasUserConsent = categories.every((c) => consentedCategories[c])
186187
return hasUserConsent
187188
})

packages/consent/consent-tools/src/types/settings.ts

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -50,32 +50,14 @@ export interface CreateWrapperSettings {
5050
integrationCategoryMappings?: IntegrationCategoryMappings
5151

5252
/**
53-
* Predicate function to override default logic around whether or not to load an integration.
54-
* @default
55-
* ```ts
56-
* // consent if user consents to at least one category defined in the integration
57-
* (integrationCategories, categories, _info) => {
58-
* if (!integrationCategories.length) return true
59-
* return integrationCategories.some((c) => categories[c])
60-
* }
61-
* ```
62-
*
63-
* @example -
64-
* ```ts
65-
* (integrationCategories, categories, _info) => {
66-
* // consent if user consents to _all_ categories defined in the integration
67-
* if (!integrationCategories.length) return true
68-
* return integrationCategories.every((c) => categories[c])
69-
* }
70-
* ```
71-
*
53+
* 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.
7254
* @example
7355
* ```ts
74-
* // count consent as usual, but always disable a particular plugin
75-
* (integrationCategories, categories, { creationName }) => {
56+
* // Always disable a particular plugin
57+
* const shouldEnableIntegration = (integrationCategories, categories, { creationName }) => {
7658
* if (creationName === 'FullStory') return false
7759
* if (!integrationCategories.length) return true
78-
* return integrationCategories.some((c) => categories[c])
60+
* return integrationCategories.every((c) => categories[c])
7961
* }
8062
* ```
8163
*/

0 commit comments

Comments
 (0)