diff --git a/src/ecommerce.js b/src/ecommerce.js index 585f0d8e..2b6b9208 100644 --- a/src/ecommerce.js +++ b/src/ecommerce.js @@ -525,6 +525,8 @@ export default function Ecommerce(mpInstance) { this.createCommerceEventObject = function(customFlags, options) { var baseEvent; + // https://go.mparticle.com/work/SQDSDKS-4801 + var { extend } = mpInstance._Helpers; mpInstance.Logger.verbose( Messages.InformationMessages.StartingLogCommerceEvent @@ -539,7 +541,7 @@ export default function Ecommerce(mpInstance) { baseEvent.CurrencyCode = mpInstance._Store.currencyCode; baseEvent.ShoppingCart = []; - baseEvent.CustomFlags = customFlags; + baseEvent.CustomFlags = extend(baseEvent.CustomFlags, customFlags); return baseEvent; } else { diff --git a/test/src/config/utils.js b/test/src/config/utils.js index 46e15f84..06b6476a 100644 --- a/test/src/config/utils.js +++ b/test/src/config/utils.js @@ -172,10 +172,14 @@ var pluses = /\+/g, return mParticle.getInstance()._Persistence.getLocalStorage(); } }, + // https://go.mparticle.com/work/SQDSDKS-6894 findEventFromBatch = function(batch, eventName) { if (batch.events.length) { return batch.events.find(function(event) { switch (event.event_type) { + case 'screen_view': + // The SDK sets "PageView" as the default for a screen_name if one is not provided + return ['PageView', eventName].includes(event.data.screen_name); case 'commerce_event': if (event.data.product_action) { return event.data.product_action.action === eventName; @@ -232,7 +236,6 @@ var pluses = /\+/g, return null; } var batch = JSON.parse(request[1].body); - if (!batch.events) { return null; } diff --git a/test/src/tests-event-logging.js b/test/src/tests-event-logging.js index aa942b85..6c52f657 100644 --- a/test/src/tests-event-logging.js +++ b/test/src/tests-event-logging.js @@ -427,7 +427,7 @@ describe('event logging', function() { const pageViewEvent = findEventFromRequest( fetchMock.calls(), - 'screen_view' + 'My Page View' ); Should(pageViewEvent).be.ok(); @@ -456,7 +456,7 @@ describe('event logging', function() { const pageViewEvent = findEventFromRequest( fetchMock.calls(), - 'screen_view' + 'test' ); Should(pageViewEvent).be.ok(); @@ -480,7 +480,7 @@ describe('event logging', function() { const pageViewEvent = findEventFromRequest( fetchMock.calls(), - 'screen_view' + 'test bypass' ); Should(pageViewEvent).not.be.ok(); @@ -494,7 +494,7 @@ describe('event logging', function() { mParticle.logPageView('test1', 'invalid', null); const pageViewEvent = findEventFromRequest( fetchMock.calls(), - 'screen_view' + 'test1' ); Should(pageViewEvent).not.be.ok(); @@ -510,7 +510,7 @@ describe('event logging', function() { const pageViewEvent = findEventFromRequest( fetchMock.calls(), - 'screen_view' + 'test' ); Should(pageViewEvent).not.be.ok(); diff --git a/test/src/tests-integration-capture.ts b/test/src/tests-integration-capture.ts index 7b68034a..9b6cf403 100644 --- a/test/src/tests-integration-capture.ts +++ b/test/src/tests-integration-capture.ts @@ -64,4 +64,205 @@ describe('Integration Capture', () => { 'Facebook.BrowserId': '54321', }); }); + + it('should add captured integrations to event custom flags, prioritizing passed in custom flags', async () => { + await waitForCondition(hasIdentifyReturned); + window.mParticle.logEvent( + 'Test Event', + mParticle.EventType.Navigation, + { mykey: 'myvalue' }, + { 'Facebook.ClickId': 'passed-in' }, + ); + + const testEvent = findEventFromRequest(fetchMock.calls(), 'Test Event'); + + + expect(testEvent).to.have.property('data'); + expect(testEvent.data).to.have.property('event_name', 'Test Event'); + expect(testEvent.data).to.have.property('custom_flags'); + expect(testEvent.data.custom_flags).to.deep.equal({ + 'Facebook.ClickId': 'passed-in', + 'Facebook.BrowserId': '54321', + }); + }); + + it('should add captured integrations to page view custom flags', async () => { + await waitForCondition(hasIdentifyReturned); + + window.mParticle.logPageView( + 'Test Page View', + {'foo-attr': 'bar-attr'} + ); + + const testEvent = findEventFromRequest(fetchMock.calls(), 'Test Page View'); + + const initialTimestamp = window.mParticle.getInstance()._IntegrationCapture.initialTimestamp; + + expect(testEvent).to.have.property('data'); + expect(testEvent.data).to.have.property('screen_name', 'Test Page View'); + expect(testEvent.data).to.have.property('custom_flags'); + expect(testEvent.data.custom_flags).to.deep.equal({ + 'Facebook.ClickId': `fb.1.${initialTimestamp}.1234`, + 'Facebook.BrowserId': '54321', + }); + }); + + it('should add captured integrations to page view custom flags, prioritizing passed in custom flags', async () => { + await waitForCondition(hasIdentifyReturned); + window.mParticle.logPageView( + 'Test Page View', + {'foo-attr': 'bar-attr'}, + {'Facebook.ClickId': 'passed-in'}, + ); + + const testEvent = findEventFromRequest(fetchMock.calls(), 'Test Page View'); + + expect(testEvent).to.have.property('data'); + expect(testEvent.data).to.have.property('screen_name', 'Test Page View'); + expect(testEvent.data).to.have.property('custom_flags'); + expect(testEvent.data.custom_flags).to.deep.equal({ + 'Facebook.ClickId': 'passed-in', + 'Facebook.BrowserId': '54321', + }); + }); + + it('should add captured integrations to commerce event custom flags', async () => { + await waitForCondition(hasIdentifyReturned); + + const product1 = mParticle.eCommerce.createProduct('iphone', 'iphoneSKU', 999, 1); + const product2 = mParticle.eCommerce.createProduct('galaxy', 'galaxySKU', 799, 1); + + const transactionAttributes = { + Id: 'foo-transaction-id', + Revenue: 430.00, + Tax: 30 + }; + + const customAttributes = {sale: true}; + const customFlags = {foo: 'bar'}; + + mParticle.eCommerce.logProductAction( + mParticle.ProductActionType.Purchase, + [product1, product2], + customAttributes, + customFlags, + transactionAttributes); + + const testEvent = findEventFromRequest(fetchMock.calls(), 'purchase'); + + const initialTimestamp = window.mParticle.getInstance()._IntegrationCapture.initialTimestamp; + + expect(testEvent.data.product_action).to.have.property('action', 'purchase'); + expect(testEvent.data).to.have.property('custom_flags'); + expect(testEvent.data.custom_flags).to.deep.equal({ + foo: 'bar', + 'Facebook.ClickId': `fb.1.${initialTimestamp}.1234`, + 'Facebook.BrowserId': '54321', + }); + }); + + it('should add captured integrations to commerce event custom flags, prioritizing passed in flags', async () => { + await waitForCondition(hasIdentifyReturned); + + const product1 = mParticle.eCommerce.createProduct('iphone', 'iphoneSKU', 999, 1); + const product2 = mParticle.eCommerce.createProduct('galaxy', 'galaxySKU', 799, 1); + + const transactionAttributes = { + Id: 'foo-transaction-id', + Revenue: 430.00, + Tax: 30 + }; + + const customAttributes = {sale: true}; + const customFlags = { + 'Facebook.ClickId': 'passed-in' + }; + + mParticle.eCommerce.logProductAction( + mParticle.ProductActionType.Purchase, + [product1, product2], + customAttributes, + customFlags, + transactionAttributes); + + + const testEvent = findEventFromRequest(fetchMock.calls(), 'purchase'); + + expect(testEvent.data.product_action).to.have.property('action', 'purchase'); + expect(testEvent.data).to.have.property('custom_flags'); + expect(testEvent.data.custom_flags).to.deep.equal({ + 'Facebook.ClickId': 'passed-in', + 'Facebook.BrowserId': '54321', + }); + }); + + it('should add captured integrations to commerce event custom flags', async () => { + await waitForCondition(hasIdentifyReturned); + + const product1 = mParticle.eCommerce.createProduct('iphone', 'iphoneSKU', 999, 1); + const product2 = mParticle.eCommerce.createProduct('galaxy', 'galaxySKU', 799, 1); + + const transactionAttributes = { + Id: 'foo-transaction-id', + Revenue: 430.00, + Tax: 30 + }; + + const customAttributes = {sale: true}; + const customFlags = {foo: 'bar'}; + + mParticle.eCommerce.logProductAction( + mParticle.ProductActionType.Purchase, + [product1, product2], + customAttributes, + customFlags, + transactionAttributes); + + const testEvent = findEventFromRequest(fetchMock.calls(), 'purchase'); + + const initialTimestamp = window.mParticle.getInstance()._IntegrationCapture.initialTimestamp; + + expect(testEvent.data.product_action).to.have.property('action', 'purchase'); + expect(testEvent.data).to.have.property('custom_flags'); + expect(testEvent.data.custom_flags).to.deep.equal({ + foo: 'bar', + 'Facebook.ClickId': `fb.1.${initialTimestamp}.1234`, + 'Facebook.BrowserId': '54321', + }); + }); + + it('should add captured integrations to commerce event custom flags, prioritizing passed in flags', async () => { + await waitForCondition(hasIdentifyReturned); + + const product1 = mParticle.eCommerce.createProduct('iphone', 'iphoneSKU', 999, 1); + const product2 = mParticle.eCommerce.createProduct('galaxy', 'galaxySKU', 799, 1); + + const transactionAttributes = { + Id: 'foo-transaction-id', + Revenue: 430.00, + Tax: 30 + }; + + const customAttributes = {sale: true}; + const customFlags = { + 'Facebook.ClickId': 'passed-in' + }; + + mParticle.eCommerce.logProductAction( + mParticle.ProductActionType.Purchase, + [product1, product2], + customAttributes, + customFlags, + transactionAttributes); + + + const testEvent = findEventFromRequest(fetchMock.calls(), 'purchase'); + + expect(testEvent.data.product_action).to.have.property('action', 'purchase'); + expect(testEvent.data).to.have.property('custom_flags'); + expect(testEvent.data.custom_flags).to.deep.equal({ + 'Facebook.ClickId': 'passed-in', + 'Facebook.BrowserId': '54321', + }); + }); }); \ No newline at end of file