diff --git a/modules/33acrossIdSystem.js b/modules/33acrossIdSystem.js index 8f99846017a..fb5a7712f1f 100644 --- a/modules/33acrossIdSystem.js +++ b/modules/33acrossIdSystem.js @@ -27,6 +27,7 @@ const GVLID = 58; const STORAGE_FPID_KEY = '33acrossIdFp'; const STORAGE_TPID_KEY = '33acrossIdTp'; +const STORAGE_HEM_KEY = '33acrossIdHm' const DEFAULT_1PID_SUPPORT = true; const DEFAULT_TPID_SUPPORT = true; @@ -59,7 +60,7 @@ function calculateResponseObj(response) { }; } -function calculateQueryStringParams(pid, gdprConsentData, enabledStorageTypes) { +function calculateQueryStringParams({ pid, hem }, gdprConsentData, enabledStorageTypes) { const uspString = uspDataHandler.getConsentData(); const coppaValue = coppaDataHandler.getCoppa(); const gppConsent = gppDataHandler.getConsentData(); @@ -97,6 +98,11 @@ function calculateQueryStringParams(pid, gdprConsentData, enabledStorageTypes) { params.tp = encodeURIComponent(tp); } + const hemParam = hem || getStoredValue(STORAGE_HEM_KEY, enabledStorageTypes); + if (hemParam) { + params.sha256 = encodeURIComponent(hemParam); + } + return params; } @@ -146,7 +152,7 @@ function handleSupplementalId(key, id, storageConfig) { } /** @type {Submodule} */ -export const thirthyThreeAcrossIdSubmodule = { +export const thirtyThreeAcrossIdSubmodule = { /** * used to link submodule with config * @type {string} @@ -188,7 +194,11 @@ export const thirthyThreeAcrossIdSubmodule = { return; } - const { pid, storeFpid = DEFAULT_1PID_SUPPORT, storeTpid = DEFAULT_TPID_SUPPORT, apiUrl = API_URL } = params; + const { + storeFpid = DEFAULT_1PID_SUPPORT, + storeTpid = DEFAULT_TPID_SUPPORT, apiUrl = API_URL, + ...options + } = params; return { callback(cb) { @@ -203,7 +213,9 @@ export const thirthyThreeAcrossIdSubmodule = { } if (!responseObj.envelope) { - deleteFromStorage(MODULE_NAME); + ['', '_last', '_exp', '_cst'].forEach(suffix => { + deleteFromStorage(`${MODULE_NAME}${suffix}`); + }); } if (storeFpid) { @@ -227,7 +239,7 @@ export const thirthyThreeAcrossIdSubmodule = { cb(); } - }, calculateQueryStringParams(pid, gdprConsentData, enabledStorageTypes), { + }, calculateQueryStringParams(options, gdprConsentData, enabledStorageTypes), { method: 'GET', withCredentials: true }); @@ -246,4 +258,4 @@ export const thirthyThreeAcrossIdSubmodule = { } }; -submodule('userId', thirthyThreeAcrossIdSubmodule); +submodule('userId', thirtyThreeAcrossIdSubmodule); diff --git a/modules/33acrossIdSystem.md b/modules/33acrossIdSystem.md index e983c8ab871..b6b68622344 100644 --- a/modules/33acrossIdSystem.md +++ b/modules/33acrossIdSystem.md @@ -51,5 +51,10 @@ 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"` | +| hem | Optional | String | Hashed email address in sha256 format | `"ba4235544d6c91865fbf70fa1bdb70f2d375ded1b2b946b21c675dcbe9968cdc"` | | 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` | | storeTpid | Optional | Boolean | Indicates whether a supplemental third-party ID may be stored to improve addressability, this feature is enabled by default | `true` (default) or `false` | + +### HEM Collection + +33Across ID System supports user's hashed email, if available in storage. diff --git a/test/spec/modules/33acrossIdSystem_spec.js b/test/spec/modules/33acrossIdSystem_spec.js index 6ec3554d353..93e6a41d928 100644 --- a/test/spec/modules/33acrossIdSystem_spec.js +++ b/test/spec/modules/33acrossIdSystem_spec.js @@ -1,4 +1,4 @@ -import { thirthyThreeAcrossIdSubmodule, storage, domainUtils } from 'modules/33acrossIdSystem.js'; +import { thirtyThreeAcrossIdSubmodule, storage, domainUtils } from 'modules/33acrossIdSystem.js'; import * as utils from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; @@ -10,13 +10,13 @@ import {attachIdSystem} from '../../../modules/userId/index.js'; describe('33acrossIdSystem', () => { describe('name', () => { it('should expose the name of the submodule', () => { - expect(thirthyThreeAcrossIdSubmodule.name).to.equal('33acrossId'); + expect(thirtyThreeAcrossIdSubmodule.name).to.equal('33acrossId'); }); }); describe('gvlid', () => { it('should expose the vendor id', () => { - expect(thirthyThreeAcrossIdSubmodule.gvlid).to.equal(58); + expect(thirtyThreeAcrossIdSubmodule.gvlid).to.equal(58); }); }); @@ -24,7 +24,7 @@ describe('33acrossIdSystem', () => { it('should call endpoint and handle valid response', () => { const completeCallback = sinon.spy(); - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -65,7 +65,7 @@ describe('33acrossIdSystem', () => { it('should store the provided first-party ID in a cookie', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', ...opts @@ -103,7 +103,7 @@ describe('33acrossIdSystem', () => { it('should store the provided first-party ID in local storage', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', ...opts @@ -139,7 +139,7 @@ describe('33acrossIdSystem', () => { it('should store the provided first-party ID in each storage type', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', ...opts @@ -181,7 +181,7 @@ describe('33acrossIdSystem', () => { it('should wipe any existing first-party ID from storage', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', ...opts @@ -224,7 +224,7 @@ describe('33acrossIdSystem', () => { it('should store the provided third-party ID in a cookie', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', ...opts @@ -262,7 +262,7 @@ describe('33acrossIdSystem', () => { it('should store the provided third-party ID in local storage', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', ...opts @@ -298,7 +298,7 @@ describe('33acrossIdSystem', () => { it('should store the provided third-party ID in each storage type', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', ...opts @@ -340,7 +340,7 @@ describe('33acrossIdSystem', () => { it('should wipe any existing third-party ID from storage', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', ...opts @@ -383,7 +383,7 @@ describe('33acrossIdSystem', () => { it('should not store the provided first-party ID in a cookie', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', storeFpid: false @@ -421,7 +421,7 @@ describe('33acrossIdSystem', () => { it('should not store the provided first-party ID in local storage', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', storeFpid: false @@ -459,7 +459,7 @@ describe('33acrossIdSystem', () => { it('should not store the provided third-party ID in a cookie', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', storeTpid: false @@ -495,7 +495,7 @@ describe('33acrossIdSystem', () => { it('should not store the provided third-party ID in local storage', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', storeTpid: false @@ -532,7 +532,7 @@ describe('33acrossIdSystem', () => { it('should wipe any existing "envelope" ID from storage', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' }, @@ -558,8 +558,10 @@ describe('33acrossIdSystem', () => { expires: 1645667805067 })); - expect(removeDataFromLocalStorage.calledWith('33acrossId')).to.be.true; - expect(setCookie.calledWithExactly('33acrossId', '', sinon.match.string, 'Lax', 'foo.com')).to.be.true; + ['', '_last', '_exp', '_cst'].forEach(suffix => { + expect(removeDataFromLocalStorage.calledWith(`33acrossId${suffix}`)).to.be.true; + expect(setCookie.calledWithExactly(`33acrossId${suffix}`, '', sinon.match.string, 'Lax', 'foo.com')).to.be.true; + }); removeDataFromLocalStorage.restore(); setCookie.restore(); @@ -571,7 +573,7 @@ describe('33acrossIdSystem', () => { it('should log a warning and don\'t expect a call to the endpoint', () => { const logWarnSpy = sinon.spy(utils, 'logWarn'); - const result = thirthyThreeAcrossIdSubmodule.getId({ + const result = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -589,7 +591,7 @@ describe('33acrossIdSystem', () => { context('when GDPR doesn\'t apply', () => { it('should call endpoint with \'gdpr=0\'', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -607,7 +609,7 @@ describe('33acrossIdSystem', () => { context('but the GDPR consent string is given', () => { it('should call endpoint with the GDPR consent string', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -628,7 +630,7 @@ describe('33acrossIdSystem', () => { context('when a valid US Privacy string is given', () => { it('should call endpoint with the US Privacy parameter', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -649,7 +651,7 @@ describe('33acrossIdSystem', () => { context('when an invalid US Privacy is given', () => { it('should call endpoint without the US Privacy parameter', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -671,7 +673,7 @@ describe('33acrossIdSystem', () => { context('when coppa is enabled', () => { it('should call endpoint with an enabled coppa signal', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -692,7 +694,7 @@ describe('33acrossIdSystem', () => { context('when coppa is not enabled', () => { it('should call endpoint with coppa signal not enabled', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -726,7 +728,7 @@ describe('33acrossIdSystem', () => { { gppString: 'foo', expected: 'foo' }, ].forEach(({ gppString, expected }, index) => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -752,7 +754,7 @@ describe('33acrossIdSystem', () => { { applicableSections: ['1', '2'], expected: '1%2C2' }, ].forEach(({ applicableSections, expected }, index) => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -773,7 +775,7 @@ describe('33acrossIdSystem', () => { context('when a first-party ID is present in local storage', () => { it('should call endpoint with the encoded first-party ID included', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' }, @@ -798,7 +800,7 @@ describe('33acrossIdSystem', () => { context('when a first-party ID is present in cookie storage', () => { it('should call endpoint with the first-party ID included', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' }, @@ -823,7 +825,7 @@ describe('33acrossIdSystem', () => { context('when a first-party ID is not present in storage', () => { it('should not call endpoint with the first-party ID included', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -840,7 +842,7 @@ describe('33acrossIdSystem', () => { context('when a third-party ID is present in local storage', () => { it('should call endpoint with the encoded third-party ID included', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' }, @@ -865,7 +867,7 @@ describe('33acrossIdSystem', () => { context('when a third-party ID is present in cookie storage', () => { it('should call endpoint with the third-party ID included', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' }, @@ -890,7 +892,7 @@ describe('33acrossIdSystem', () => { context('when a third-party ID is not present in storage', () => { it('should not call endpoint with the third-party ID included', () => { const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -904,11 +906,107 @@ describe('33acrossIdSystem', () => { }); }); + context('when a hashed email is provided via configuration options', () => { + it('should call endpoint with the hashed email included', () => { + const completeCallback = () => {}; + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ + params: { + pid: '12345', + hem: '33acrossIdHmValue+' + }, + enabledStorageTypes: [ 'html5' ], + storage: {} + }); + + // Prioritizes the hem given via config options over the one stored in LS. + sinon.stub(storage, 'getDataFromLocalStorage') + .withArgs('33acrossIdHm') + .returns('33acrossIdHmValueLS'); + + callback(completeCallback); + + const [request] = server.requests; + + expect(request.url).to.contain('sha256=33acrossIdHmValue%2B'); + + storage.getDataFromLocalStorage.restore(); + }); + }); + + context('when a hashed email is NOT provided via configuration options', () => { + context('but it\'s provided via local storage', () => { + it('should call endpoint with the hashed email included', () => { + const completeCallback = () => {}; + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ + params: { + pid: '12345' + }, + enabledStorageTypes: [ 'html5' ], + storage: {} + }); + + sinon.stub(storage, 'getDataFromLocalStorage') + .withArgs('33acrossIdHm') + .returns('33acrossIdHmValue+'); + + callback(completeCallback); + + const [request] = server.requests; + + expect(request.url).to.contain('sha256=33acrossIdHmValue%2B'); + + storage.getDataFromLocalStorage.restore(); + }); + }); + + context('but it\'s provided via cookie storage', () => { + it('should call endpoint with the hashed email included', () => { + const completeCallback = () => {}; + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ + params: { + pid: '12345' + }, + enabledStorageTypes: [ 'cookie' ], + storage: {} + }); + + sinon.stub(storage, 'getCookie') + .withArgs('33acrossIdHm') + .returns('33acrossIdHmValue'); + + callback(completeCallback); + + const [request] = server.requests; + + expect(request.url).to.contain('sha256=33acrossIdHmValue'); + + storage.getCookie.restore(); + }); + }); + + context('and hashed email is not present in storage', () => { + it('should not call endpoint with the hashed email included', () => { + const completeCallback = () => {}; + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ + params: { + pid: '12345' + } + }); + + callback(completeCallback); + + const [request] = server.requests; + + expect(request.url).not.to.contain('sha256='); + }); + }); + }); + context('when the partner ID is not given', () => { it('should log an error', () => { const logErrorSpy = sinon.spy(utils, 'logError'); - thirthyThreeAcrossIdSubmodule.getId({ + thirtyThreeAcrossIdSubmodule.getId({ params: { /* No 'pid' param */ } }); @@ -922,7 +1020,7 @@ describe('33acrossIdSystem', () => { it('should log an error', () => { const logErrorSpy = sinon.spy(utils, 'logError'); - thirthyThreeAcrossIdSubmodule.getId({ + thirtyThreeAcrossIdSubmodule.getId({ params: { pid: 123456 // PID must be a string } @@ -939,7 +1037,7 @@ describe('33acrossIdSystem', () => { const logErrorSpy = sinon.spy(utils, 'logError'); const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -953,7 +1051,7 @@ describe('33acrossIdSystem', () => { 'Content-Type': 'application/json' }, 'invalid response'); - expect(logErrorSpy.lastCall.args[0]).to.eq(`${thirthyThreeAcrossIdSubmodule.name}: ID reading error:`); + expect(logErrorSpy.lastCall.args[0]).to.eq(`${thirtyThreeAcrossIdSubmodule.name}: ID reading error:`); logErrorSpy.restore(); }); @@ -961,7 +1059,7 @@ describe('33acrossIdSystem', () => { it('should execute complete callback with undefined value', () => { const completeCallback = sinon.spy(); - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -982,7 +1080,7 @@ describe('33acrossIdSystem', () => { context('when an endpoint override is given', () => { it('should call that endpoint', () => { const completeCallback = sinon.spy(); - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345', apiUrl: 'https://staging-lexicon.33across.com/v1/envelope' @@ -1012,7 +1110,7 @@ describe('33acrossIdSystem', () => { const logErrorSpy = sinon.spy(utils, 'logError'); const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -1029,7 +1127,7 @@ describe('33acrossIdSystem', () => { error: 'foo' })); - expect(logErrorSpy.calledOnceWithExactly(`${thirthyThreeAcrossIdSubmodule.name}: Unsuccessful response foo`)).to.be.true; + expect(logErrorSpy.calledOnceWithExactly(`${thirtyThreeAcrossIdSubmodule.name}: Unsuccessful response foo`)).to.be.true; logErrorSpy.restore(); }); @@ -1037,7 +1135,7 @@ describe('33acrossIdSystem', () => { it('should execute complete callback with undefined value', () => { const completeCallback = sinon.spy(); - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -1063,7 +1161,7 @@ describe('33acrossIdSystem', () => { const logMessageSpy = sinon.spy(utils, 'logMessage'); const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -1080,7 +1178,7 @@ describe('33acrossIdSystem', () => { data: {} })); - expect(logMessageSpy.calledOnceWithExactly(`${thirthyThreeAcrossIdSubmodule.name}: No envelope was received`)).to.be.true; + expect(logMessageSpy.calledOnceWithExactly(`${thirtyThreeAcrossIdSubmodule.name}: No envelope was received`)).to.be.true; logMessageSpy.restore(); }); @@ -1088,7 +1186,7 @@ describe('33acrossIdSystem', () => { it('should execute complete callback with undefined value', () => { const completeCallback = sinon.spy(); - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -1114,7 +1212,7 @@ describe('33acrossIdSystem', () => { const logErrorSpy = sinon.spy(utils, 'logError'); const completeCallback = () => {}; - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -1126,7 +1224,7 @@ describe('33acrossIdSystem', () => { request.respond(404); - expect(logErrorSpy.calledOnceWithExactly(`${thirthyThreeAcrossIdSubmodule.name}: ID error response`, 'Not Found')).to.be.true; + expect(logErrorSpy.calledOnceWithExactly(`${thirtyThreeAcrossIdSubmodule.name}: ID error response`, 'Not Found')).to.be.true; logErrorSpy.restore(); }); @@ -1134,7 +1232,7 @@ describe('33acrossIdSystem', () => { it('should execute complete callback without any value', () => { const completeCallback = sinon.spy(); - const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + const { callback } = thirtyThreeAcrossIdSubmodule.getId({ params: { pid: '12345' } @@ -1153,8 +1251,8 @@ describe('33acrossIdSystem', () => { describe('decode', () => { it('should wrap the given value inside an object literal', () => { - expect(thirthyThreeAcrossIdSubmodule.decode('foo')).to.deep.equal({ - [thirthyThreeAcrossIdSubmodule.name]: { + expect(thirtyThreeAcrossIdSubmodule.decode('foo')).to.deep.equal({ + [thirtyThreeAcrossIdSubmodule.name]: { envelope: 'foo' } }); @@ -1162,7 +1260,7 @@ describe('33acrossIdSystem', () => { }); describe('eid', () => { before(() => { - attachIdSystem(thirthyThreeAcrossIdSubmodule); + attachIdSystem(thirtyThreeAcrossIdSubmodule); }) it('33acrossId', function() { const userId = {