diff --git a/modules/33acrossIdSystem.js b/modules/33acrossIdSystem.js index e0f7435a1ecc..0f3c378551e2 100644 --- a/modules/33acrossIdSystem.js +++ b/modules/33acrossIdSystem.js @@ -25,6 +25,7 @@ const CALLER_NAME = 'pbjs'; const GVLID = 58; const STORAGE_FPID_KEY = '33acrossIdFp'; +const DEFAULT_1PID_SUPPORT = true; export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); @@ -164,7 +165,7 @@ export const thirthyThreeAcrossIdSubmodule = { return; } - const { pid, storeFpid, apiUrl = API_URL } = params; + const { pid, storeFpid = DEFAULT_1PID_SUPPORT, apiUrl = API_URL } = params; return { callback(cb) { diff --git a/modules/33acrossIdSystem.md b/modules/33acrossIdSystem.md index 8b73a43069d5..28c2da9e2e78 100644 --- a/modules/33acrossIdSystem.md +++ b/modules/33acrossIdSystem.md @@ -51,4 +51,4 @@ The following settings are available in the `params` property in `userSync.userI | Param name | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | | pid | Required | String | Partner ID provided by 33Across | `"0010b00002GYU4eBAH"` | -| storeFpid | Optional | Boolean | Indicates whether a supplemental first-party ID may be stored to improve addressability | `false` (default) or `true` | +| storeFpid | Optional | Boolean | Indicates whether a supplemental first-party ID may be stored to improve addressability, this feature is enabled by default | `true` (default) or `false` | diff --git a/test/spec/modules/33acrossIdSystem_spec.js b/test/spec/modules/33acrossIdSystem_spec.js index 364f7d2845c5..d25cea9ac1b0 100644 --- a/test/spec/modules/33acrossIdSystem_spec.js +++ b/test/spec/modules/33acrossIdSystem_spec.js @@ -50,50 +50,94 @@ describe('33acrossIdSystem', () => { expect(completeCallback.calledOnceWithExactly('foo')).to.be.true; }); - context('if the use of a first-party ID has been enabled', () => { - context('and the response includes a first-party ID', () => { - context('and the storage type is "cookie"', () => { - it('should store the provided first-party ID in a cookie', () => { - const completeCallback = () => {}; - - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ - params: { - pid: '12345', - storeFpid: true - }, - storage: { - type: 'cookie', - expires: 30 - } + const additionalOptions = { + 'by an option': { storeFpid: true }, + 'by default': { } // No storeFpid, default value should be true + }; + + Object.entries(additionalOptions).forEach(([caseTitle, opts]) => { + context(`if the use of a first-party ID has been enabled ${caseTitle}`, () => { + context('and the response includes a first-party ID', () => { + context('and the storage type is "cookie"', () => { + it('should store the provided first-party ID in a cookie', () => { + const completeCallback = () => {}; + + const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + params: { + pid: '12345', + ...opts + }, + storage: { + type: 'cookie', + expires: 30 + } + }); + + callback(completeCallback); + + const [request] = server.requests; + + const setCookie = sinon.stub(storage, 'setCookie'); + const cookiesAreEnabled = sinon.stub(storage, 'cookiesAreEnabled').returns(true); + + request.respond(200, { + 'Content-Type': 'application/json' + }, JSON.stringify({ + succeeded: true, + data: { + envelope: 'foo', + fp: 'bar' + }, + expires: 1645667805067 + })); + + expect(setCookie.calledOnceWithExactly('33acrossIdFp', 'bar', sinon.match.string, 'Lax')).to.be.true; + + setCookie.restore(); + cookiesAreEnabled.restore(); }); + }); - callback(completeCallback); + context('and the storage type is "html5"', () => { + it('should store the provided first-party ID in local storage', () => { + const completeCallback = () => {}; - const [request] = server.requests; + const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + params: { + pid: '12345', + storeFpid: true + }, + storage: { + type: 'html5' + } + }); - const setCookie = sinon.stub(storage, 'setCookie'); - const cookiesAreEnabled = sinon.stub(storage, 'cookiesAreEnabled').returns(true); + callback(completeCallback); - request.respond(200, { - 'Content-Type': 'application/json' - }, JSON.stringify({ - succeeded: true, - data: { - envelope: 'foo', - fp: 'bar' - }, - expires: 1645667805067 - })); + const [request] = server.requests; - expect(setCookie.calledOnceWithExactly('33acrossIdFp', 'bar', sinon.match.string, 'Lax')).to.be.true; + const setDataInLocalStorage = sinon.stub(storage, 'setDataInLocalStorage'); - setCookie.restore(); - cookiesAreEnabled.restore(); + request.respond(200, { + 'Content-Type': 'application/json' + }, JSON.stringify({ + succeeded: true, + data: { + envelope: 'foo', + fp: 'bar' + }, + expires: 1645667805067 + })); + + expect(setDataInLocalStorage.calledOnceWithExactly('33acrossIdFp', 'bar')).to.be.true; + + setDataInLocalStorage.restore(); + }); }); }); - context('and the storage type is "html5"', () => { - it('should store the provided first-party ID in local storage', () => { + context('and the response lacks a first-party ID', () => { + it('should wipe any existing first-party ID from storage', () => { const completeCallback = () => {}; const { callback } = thirthyThreeAcrossIdSubmodule.getId({ @@ -110,64 +154,27 @@ describe('33acrossIdSystem', () => { const [request] = server.requests; - const setDataInLocalStorage = sinon.stub(storage, 'setDataInLocalStorage'); + const removeDataFromLocalStorage = sinon.stub(storage, 'removeDataFromLocalStorage'); + const setCookie = sinon.stub(storage, 'setCookie'); + const cookiesAreEnabled = sinon.stub(storage, 'cookiesAreEnabled').returns(true); request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ succeeded: true, data: { - envelope: 'foo', - fp: 'bar' + envelope: 'foo' // no 'fp' field }, expires: 1645667805067 })); - expect(setDataInLocalStorage.calledOnceWithExactly('33acrossIdFp', 'bar')).to.be.true; - - setDataInLocalStorage.restore(); - }); - }); - }); + expect(removeDataFromLocalStorage.calledOnceWithExactly('33acrossIdFp')).to.be.true; + expect(setCookie.calledOnceWithExactly('33acrossIdFp', '', sinon.match.string, 'Lax')).to.be.true; - context('and the response lacks a first-party ID', () => { - it('should wipe any existing first-party ID from storage', () => { - const completeCallback = () => {}; - - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ - params: { - pid: '12345', - storeFpid: true - }, - storage: { - type: 'html5' - } + removeDataFromLocalStorage.restore(); + setCookie.restore(); + cookiesAreEnabled.restore(); }); - - callback(completeCallback); - - const [request] = server.requests; - - const removeDataFromLocalStorage = sinon.stub(storage, 'removeDataFromLocalStorage'); - const setCookie = sinon.stub(storage, 'setCookie'); - const cookiesAreEnabled = sinon.stub(storage, 'cookiesAreEnabled').returns(true); - - request.respond(200, { - 'Content-Type': 'application/json' - }, JSON.stringify({ - succeeded: true, - data: { - envelope: 'foo' // no 'fp' field - }, - expires: 1645667805067 - })); - - expect(removeDataFromLocalStorage.calledOnceWithExactly('33acrossIdFp')).to.be.true; - expect(setCookie.calledOnceWithExactly('33acrossIdFp', '', sinon.match.string, 'Lax')).to.be.true; - - removeDataFromLocalStorage.restore(); - setCookie.restore(); - cookiesAreEnabled.restore(); }); }); }); @@ -179,8 +186,8 @@ describe('33acrossIdSystem', () => { const { callback } = thirthyThreeAcrossIdSubmodule.getId({ params: { - pid: '12345' - // no storeFpid param + pid: '12345', + storeFpid: false }, storage: { type: 'cookie', @@ -217,8 +224,8 @@ describe('33acrossIdSystem', () => { const { callback } = thirthyThreeAcrossIdSubmodule.getId({ params: { - pid: '12345' - // no storeFpid param + pid: '12345', + storeFpid: false }, storage: { type: 'html5'