Skip to content

Commit

Permalink
Light consent refactoring to remove tech debt / reduce footprint (#1071)
Browse files Browse the repository at this point in the history
  • Loading branch information
silesky committed Apr 22, 2024
1 parent f97d3da commit a102cbb
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 163 deletions.
6 changes: 6 additions & 0 deletions .changeset/smooth-mirrors-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@segment/analytics-consent-tools': patch
'@segment/analytics-consent-wrapper-onetrust': patch
---

Light consent tools and onetrust refactoring to reduce code footprint.
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ export class AnalyticsService {
validateAnalyticsInstance(analytics)
this.settings = options
this.uninitializedAnalytics = analytics

// store the raw analytics load instance, because we may replace it later
this.ogAnalyticsLoad = analytics.load.bind(this.uninitializedAnalytics)
this.ogAnalyticsLoad = analytics.load.bind(analytics)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import {
domainGroupMock,
} from '../../test-helpers/mocks'

const getConsentedGroupIdsSpy = jest
.spyOn(OneTrustAPI, 'getConsentedGroupIds')
.mockImplementationOnce(() => {
throw new Error('not implemented')
})
const getNormalizedActiveGroupIds = jest.spyOn(
OneTrustAPI,
'getNormalizedActiveGroupIds'
)

const createWrapperSpyHelper = {
_spy: jest.spyOn(ConsentTools, 'createWrapper'),
Expand All @@ -31,18 +30,18 @@ const createWrapperSpyHelper = {
.registerOnConsentChanged!
},
}

jest
.spyOn(OneTrustAPI, 'getOneTrustGlobal')
.mockImplementation(() => OneTrustMockGlobal)

/**
* These tests are not meant to be comprehensive, but they should cover the most important cases.
* We should prefer unit tests for most functionality (see lib/__tests__)
*/
describe('High level "integration" tests', () => {
let checkResolveWhen = () => {}
beforeEach(() => {
jest
.spyOn(OneTrustAPI, 'getOneTrustGlobal')
.mockImplementation(() => OneTrustMockGlobal)
getConsentedGroupIdsSpy.mockReset()
Object.values(OneTrustMockGlobal).forEach((fn) => fn.mockReset())
/**
* Typically, resolveWhen triggers when a predicate is true. We can manually 'check' so we don't have to use timeouts.
*/
Expand All @@ -60,7 +59,7 @@ describe('High level "integration" tests', () => {
it('should support opt-in', async () => {
withOneTrust(analyticsMock)

getConsentedGroupIdsSpy.mockImplementation(() => [
getNormalizedActiveGroupIds.mockImplementation(() => [
domainGroupMock.StrictlyNeccessary.CustomGroupId,
])

Expand Down Expand Up @@ -125,7 +124,7 @@ describe('High level "integration" tests', () => {
},
})
OneTrustMockGlobal.IsAlertBoxClosed.mockReturnValueOnce(true)
getConsentedGroupIdsSpy.mockImplementation(() => [
getNormalizedActiveGroupIds.mockImplementation(() => [
domainGroupMock.StrictlyNeccessary.CustomGroupId,
])
const load = jest.fn()
Expand All @@ -143,7 +142,7 @@ describe('High level "integration" tests', () => {

OneTrustMockGlobal.GetDomainData.mockReturnValue(domainDataMock)
OneTrustMockGlobal.IsAlertBoxClosed.mockReturnValueOnce(true)
getConsentedGroupIdsSpy.mockImplementation(() => [
getNormalizedActiveGroupIds.mockImplementation(() => [
domainGroupMock.StrictlyNeccessary.CustomGroupId,
])
const shouldLoadSegment = Promise.resolve(
Expand All @@ -157,7 +156,7 @@ describe('High level "integration" tests', () => {

it('should not load at all if no groups are defined', async () => {
withOneTrust(analyticsMock)
getConsentedGroupIdsSpy.mockImplementation(() => [])
getNormalizedActiveGroupIds.mockImplementation(() => [])
const shouldLoadSegment = Promise.resolve(
createWrapperSpyHelper.shouldLoadSegment({} as any)
)
Expand All @@ -173,7 +172,7 @@ describe('High level "integration" tests', () => {
...domainDataMock,
ShowAlertNotice: false, // meaning, it's open
})
getConsentedGroupIdsSpy.mockImplementation(() => [
getNormalizedActiveGroupIds.mockImplementation(() => [
domainGroupMock.StrictlyNeccessary.CustomGroupId,
])
const shouldLoadSegment = Promise.resolve(
Expand All @@ -198,7 +197,7 @@ describe('High level "integration" tests', () => {
domainGroupMock.Targeting,
],
})
getConsentedGroupIdsSpy.mockImplementation(() => [
getNormalizedActiveGroupIds.mockImplementation(() => [
domainGroupMock.StrictlyNeccessary.CustomGroupId,
])
const categories = createWrapperSpyHelper.getCategories()
Expand Down

This file was deleted.

37 changes: 17 additions & 20 deletions packages/consent/consent-wrapper-onetrust/src/domain/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import {
} from '@segment/analytics-consent-tools'

import {
getNormalizedCategoriesFromGroupData,
getNormalizedCategoriesFromGroupIds,
getConsentedGroupIds,
getNormalizedCategories,
getNormalizedActiveGroupIds,
getOneTrustGlobal,
coerceConsentModel,
} from '../lib/onetrust-api'
import { coerceConsentModel } from './consent-model'

export interface OneTrustSettings {
integrationCategoryMappings?: CreateWrapperSettings['integrationCategoryMappings']
Expand Down Expand Up @@ -42,7 +41,6 @@ export const withOneTrust = <Analytics extends AnyAnalytics>(
shouldLoadWrapper: async () => {
await resolveWhen(() => getOneTrustGlobal() !== undefined, 500)
},
// wait for AlertBox to be closed before segment can be loaded. If no consented groups, do not load Segment.
shouldLoadSegment: async (ctx) => {
const OneTrust = getOneTrustGlobal()!
const consentModel =
Expand All @@ -53,30 +51,29 @@ export const withOneTrust = <Analytics extends AnyAnalytics>(
return ctx.load({
consentModel: 'opt-out',
})
} else {
await resolveWhen(() => {
return (
// if any groups at all are consented to
Boolean(getNormalizedActiveGroupIds().length) &&
// if show banner is unchecked in the UI
(OneTrust.GetDomainData().ShowAlertNotice === false ||
// if alert box is closed by end user
OneTrust.IsAlertBoxClosed())
)
}, 500)
return ctx.load({ consentModel: 'opt-in' })
}
await resolveWhen(() => {
return (
// if any groups at all are consented to
Boolean(getConsentedGroupIds().length) &&
// if show banner is unchecked in the UI
(OneTrust.GetDomainData().ShowAlertNotice === false ||
// if alert box is closed by end user
OneTrust.IsAlertBoxClosed())
)
}, 500)
return ctx.load({ consentModel: 'opt-in' })
},
getCategories: () => {
const results = getNormalizedCategoriesFromGroupData()
const results = getNormalizedCategories()
return results
},
registerOnConsentChanged: settings.disableConsentChangedEvent
? undefined
: (setCategories) => {
getOneTrustGlobal()!.OnConsentChanged((event) => {
const normalizedCategories = getNormalizedCategoriesFromGroupIds(
event.detail
)
const normalizedCategories = getNormalizedCategories(event.detail)
setCategories(normalizedCategories)
})
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import '../../test-helpers/onetrust-globals.d.ts'

import {
getConsentedGroupIds,
getGroupDataFromGroupIds,
getNormalizedCategoriesFromGroupData,
getNormalizedActiveGroupIds,
getOneTrustActiveGroups,
getNormalizedCategoriesFromGroupIds,
getNormalizedCategories,
getOneTrustGlobal,
getAllGroups,
} from '../onetrust-api'
Expand Down Expand Up @@ -74,17 +72,6 @@ describe(getAllGroups, () => {
})
})

describe(getNormalizedCategoriesFromGroupData, () => {
it('should return a set of groups', () => {
expect(
getNormalizedCategoriesFromGroupData({
userSetConsentGroups: [{ groupId: 'C0003' }],
userDeniedConsentGroups: [{ groupId: 'C0001' }, { groupId: 'C0002' }],
})
).toEqual({ C0003: true, C0001: false, C0002: false })
})
})

describe(getOneTrustActiveGroups, () => {
it('should return the global string', () => {
window.OnetrustActiveGroups = 'hello'
Expand All @@ -110,25 +97,31 @@ describe(getOneTrustActiveGroups, () => {
})
})

describe(getConsentedGroupIds, () => {
describe(getNormalizedActiveGroupIds, () => {
it('should normalize groupIds', () => {
expect(getConsentedGroupIds(',C0001,')).toEqual(['C0001'])
expect(getConsentedGroupIds('C0001,C0004')).toEqual(['C0001', 'C0004'])
expect(getConsentedGroupIds(',C0001,C0004')).toEqual(['C0001', 'C0004'])
expect(getConsentedGroupIds(',')).toEqual([])
expect(getConsentedGroupIds('')).toEqual([])
expect(getConsentedGroupIds(',,')).toEqual([])
expect(getNormalizedActiveGroupIds(',C0001,')).toEqual(['C0001'])
expect(getNormalizedActiveGroupIds('C0001,C0004')).toEqual([
'C0001',
'C0004',
])
expect(getNormalizedActiveGroupIds(',C0001,C0004')).toEqual([
'C0001',
'C0004',
])
expect(getNormalizedActiveGroupIds(',')).toEqual([])
expect(getNormalizedActiveGroupIds('')).toEqual([])
expect(getNormalizedActiveGroupIds(',,')).toEqual([])
})

it('should return an empty array if no groups are defined', () => {
// @ts-ignore
window.OnetrustActiveGroups = undefined
expect(getConsentedGroupIds()).toEqual([])
expect(getNormalizedActiveGroupIds()).toEqual([])
})
})

describe(getGroupDataFromGroupIds, () => {
it('should partition groups into consent/deny', () => {
describe(getNormalizedCategories, () => {
it('should set any groups that are not in active groups to false', () => {
window.OnetrustActiveGroups = ',C0001,C0004'
window.OneTrust = {
...OneTrustMockGlobal,
Expand All @@ -147,27 +140,45 @@ describe(getGroupDataFromGroupIds, () => {
],
}),
}
const data = getGroupDataFromGroupIds()

expect(data.userSetConsentGroups).toEqual([
const categories = getNormalizedCategories()
expect(categories).toMatchInlineSnapshot(`
{
groupId: 'C0001',
},
{
groupId: 'C0004',
},
])
"C0001": true,
"C0004": true,
"SOME_OTHER_GROUP": false,
}
`)
})

expect(data.userDeniedConsentGroups).toEqual([
it('should ignore any groups that are not in domain data', () => {
window.OnetrustActiveGroups = ',C0001,C000X'
window.OneTrust = {
...OneTrustMockGlobal,
GetDomainData: () => ({
...domainDataMock,
Groups: [
{
CustomGroupId: 'C0001',
},
{
CustomGroupId: 'C0004',
},
{
CustomGroupId: 'SOME_OTHER_GROUP',
},
],
}),
}
const categories = getNormalizedCategories()
expect(categories).toMatchInlineSnapshot(`
{
groupId: 'SOME_OTHER_GROUP',
},
])
"C0001": true,
"C0004": false,
"SOME_OTHER_GROUP": false,
}
`)
})
})

describe(getNormalizedCategoriesFromGroupIds, () => {
it('should get normalized categories', () => {
it('should accept an argument', () => {
window.OneTrust = {
...OneTrustMockGlobal,
GetDomainData: () => ({
Expand All @@ -185,7 +196,11 @@ describe(getNormalizedCategoriesFromGroupIds, () => {
],
}),
}
const ids = getNormalizedCategoriesFromGroupIds(['C0001'])
expect(ids).toEqual({ C0001: true, C0004: false, SOME_OTHER_GROUP: false })
const categories = getNormalizedCategories(['C0001', 'C0004'])
expect(categories).toEqual({
C0001: true,
C0004: true,
SOME_OTHER_GROUP: false,
})
})
})
Loading

0 comments on commit a102cbb

Please sign in to comment.