diff --git a/.changeset/nine-dolphins-talk.md b/.changeset/nine-dolphins-talk.md new file mode 100644 index 000000000..1e2b008f3 --- /dev/null +++ b/.changeset/nine-dolphins-talk.md @@ -0,0 +1,5 @@ +--- +'@segment/analytics-consent-tools': patch +--- + +Fix filtering of non-consented integrations 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 4ad128e06..a0f4bff13 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 @@ -424,6 +424,68 @@ describe(createWrapper, () => { updatedCDNSettings ) }) + + it('should filter ALL non-consented remote plugins when multiple integrations need to be blocked', async () => { + const mockCdnSettings = cdnSettingsBuilder + .addActionDestinationSettings( + { + creationName: 'GoogleAnalytics', + consentSettings: { + categories: ['Analytics'], + }, + }, + { + creationName: 'FacebookPixel', + consentSettings: { + categories: ['Advertising'], + }, + }, + { + creationName: 'TikTokPixel', + consentSettings: { + categories: ['Advertising'], + }, + }, + { + creationName: 'PinterestTag', + consentSettings: { + categories: ['Advertising'], + }, + } + ) + .build() + + wrapTestAnalytics({ + getCategories: () => ({ Analytics: true }), // Only Analytics consented, NOT Advertising + }) + + await analytics.load({ + ...DEFAULT_LOAD_SETTINGS, + cdnSettings: mockCdnSettings, + }) + + expect(analyticsLoadSpy).toBeCalled() + const { updatedCDNSettings } = getAnalyticsLoadLastCall() + + expect(typeof updatedCDNSettings.remotePlugins).toBe('object') + + // Only GoogleAnalytics should be present - all Advertising integrations should be filtered + assertIntegrationsContainOnly( + ['GoogleAnalytics'], + mockCdnSettings, + updatedCDNSettings + ) + + const remotePluginNames = updatedCDNSettings.remotePlugins?.map( + (p) => p.creationName + ) + + // Explicitly verify that all Advertising integrations are blocked + expect(remotePluginNames).not.toContain('FacebookPixel') + expect(remotePluginNames).not.toContain('TikTokPixel') + expect(remotePluginNames).not.toContain('PinterestTag') + expect(remotePluginNames).toContain('GoogleAnalytics') + }) }) describe('shouldDisableSegment', () => { diff --git a/packages/consent/consent-tools/src/domain/blocking-helpers.ts b/packages/consent/consent-tools/src/domain/blocking-helpers.ts index 71453fe63..b13834b02 100644 --- a/packages/consent/consent-tools/src/domain/blocking-helpers.ts +++ b/packages/consent/consent-tools/src/domain/blocking-helpers.ts @@ -101,7 +101,7 @@ export const filterDeviceModeDestinationsForOptIn = ( for (const creationName in integrations) { if (!_shouldEnableIntegrationHelper(creationName)) { logger.debug(`Disabled (opt-in): ${creationName}`) - cdnSettingsCopy.remotePlugins = remotePlugins?.filter( + cdnSettingsCopy.remotePlugins = cdnSettingsCopy.remotePlugins?.filter( (p) => p.creationName !== creationName ) // remove disabled classic destinations and locally-installed action destinations