From 47dea19e01b8afb158b35c8e97a5b27b89b1e040 Mon Sep 17 00:00:00 2001 From: Dave Linhart <132396886+AdobeLinhart@users.noreply.github.com> Date: Tue, 3 Sep 2024 02:13:30 -0600 Subject: [PATCH] MWPW-156866 [MILO][MEP] Create martech metadata table if placeholders are used in non EN page (#2780) * Initial checkin - Working state. * Optimization. Good State. * Semi-colon fix. * Linting fixes. * Unit test file creation. * Placeholders update/fix. * Fixed US data values. * Unit testing WIP. * fix unit test * unit test working * add before each * fix linter issue of using same name above * update processTrackingLabels * add coverage to attributes.js unit test * Unit test updates. --------- Co-authored-by: vgoodric --- .../personalization/personalization.js | 22 ++++ libs/martech/attributes.js | 10 +- .../createMartechMetadata.test.js | 51 +++++++++ .../personalization/mocks/placeholders.js | 103 ++++++++++++++++++ test/martech/attributes.test.js | 9 ++ 5 files changed, 193 insertions(+), 2 deletions(-) create mode 100644 test/features/personalization/createMartechMetadata.test.js create mode 100644 test/features/personalization/mocks/placeholders.js diff --git a/libs/features/personalization/personalization.js b/libs/features/personalization/personalization.js index df0f282ce8..29cfddd65d 100644 --- a/libs/features/personalization/personalization.js +++ b/libs/features/personalization/personalization.js @@ -582,6 +582,25 @@ export function parseManifestVariants(data, manifestPath, targetId) { return null; } +export async function createMartechMetadata(placeholders, config, column) { + if (config.locale.ietf === 'en-US') return; + + await import('../../martech/attributes.js').then(({ processTrackingLabels }) => { + config.mep.analyticLocalization ??= {}; + + placeholders.forEach((item, i) => { + const firstRow = placeholders[i]; + let usValue = firstRow['en-us'] || firstRow.us || firstRow.en || firstRow.key; + + if (!usValue) return; + + usValue = processTrackingLabels(usValue); + const translatedValue = processTrackingLabels(item[column]); + config.mep.analyticLocalization[translatedValue] = usValue; + }); + }); +} + /* c8 ignore start */ function parsePlaceholders(placeholders, config, selectedVariantName = '') { if (!placeholders?.length || selectedVariantName === 'default') return config; @@ -603,6 +622,9 @@ function parsePlaceholders(placeholders, config, selectedVariantName = '') { }, {}); config.placeholders = { ...(config.placeholders || {}), ...results }; } + + createMartechMetadata(placeholders, config, val); + return config; } diff --git a/libs/martech/attributes.js b/libs/martech/attributes.js index 1f0af83c53..5d661d98dc 100644 --- a/libs/martech/attributes.js +++ b/libs/martech/attributes.js @@ -6,8 +6,14 @@ const LEAD_UNDERSCORES = /^_+|_+$/g; export function processTrackingLabels(text, config, charLimit) { let analyticsValue = text?.replace(INVALID_CHARACTERS, ' ').replace(LEAD_UNDERSCORES, '').trim(); if (config) { - const { analyticLocalization, loc = analyticLocalization?.[analyticsValue] } = config; - if (loc) analyticsValue = loc; + const { analyticLocalization, mep } = config; + const mepLoc = mep?.analyticLocalization?.[analyticsValue]; + if (mepLoc) { + analyticsValue = mepLoc; + } else { + const loc = analyticLocalization?.[analyticsValue]; + if (loc) analyticsValue = loc; + } } if (charLimit) return analyticsValue.slice(0, charLimit); return analyticsValue; diff --git a/test/features/personalization/createMartechMetadata.test.js b/test/features/personalization/createMartechMetadata.test.js new file mode 100644 index 0000000000..ba6a94eae2 --- /dev/null +++ b/test/features/personalization/createMartechMetadata.test.js @@ -0,0 +1,51 @@ +import { expect } from '@esm-bundle/chai'; +import { createMartechMetadata } from '../../../libs/features/personalization/personalization.js'; +import placeholders from './mocks/placeholders.js'; + +const config = { + locale: { ietf: 'fr-fr' }, + mep: {}, +}; + +// Note that the manifestPath doesn't matter as we stub the fetch +describe('test martech metadata creation', () => { + beforeEach(() => { + config.mep = {}; + }); + it('test two non US manifests', async () => { + expect(config.mep).to.deep.equal({}); + + await createMartechMetadata(placeholders.geoTest, config, 'fr'); + expect(config.mep.analyticLocalization).to.deep.equal({ + 'value1 fr': 'value1 en us', + 'value2 fr': 'value2 en us', + 'bonjour fr': 'Hello en us', + 'buy now fr': 'buy now en us', + 'try now fr': 'try now en us', + }); + await createMartechMetadata(placeholders.secondManifestTest, config, 'fr'); + expect(config.mep.analyticLocalization).to.deep.equal({ + 'new fr': 'new en us', + 'value1 fr': 'value1 en us', + 'value2 fr': 'new2 en us', + 'bonjour fr': 'Hello en us', + 'buy now fr': 'buy now en us', + 'try now fr': 'try now en us', + }); + }); + it('test one manifest non US withou en-us keys', async () => { + await createMartechMetadata(placeholders.keyTest, config, 'fr'); + expect(config.mep.analyticLocalization).to.deep.equal({ + 'value1 fr': 'test placeholder', + 'value2 fr': 'test placeholder2', + 'bonjour fr': 'marquee headline', + 'buy now fr': 'marquee hollow', + 'try now fr': 'marquee solid', + }); + }); + it('test one manifest en-US', async () => { + config.locale.ietf = 'en-US'; + await createMartechMetadata(placeholders.keyTest, config, 'us'); + expect(config.mep).to.deep.equal({}); + }); +}); diff --git a/test/features/personalization/mocks/placeholders.js b/test/features/personalization/mocks/placeholders.js new file mode 100644 index 0000000000..6cf3a8a9d3 --- /dev/null +++ b/test/features/personalization/mocks/placeholders.js @@ -0,0 +1,103 @@ +const placeholders = { + geoTest: [ + { + key: 'test-placeholder', + 'mobile-device & us': 'US Mobile Value', + us: 'value1-us', + 'en-us': 'value1-en-us', + 'ca & not fr': 'value1-ca-not-fr', + fr: 'value1-fr', + 'mobile-device': 'value1-mobile', + }, + { + key: 'test-placeholder2', + 'mobile-device & us': 'US Mobile Value2', + us: 'value2-us', + 'en-us': 'value2-en-us', + 'ca & not fr': 'value2-ca-not-fr', + fr: 'value2-fr', + 'mobile-device': 'value2-mobile', + }, + { + key: 'marquee-headline', + 'mobile-device & us': 'hello US mobile', + us: 'hello-us', + 'en-us': 'Hello-en-us', + 'ca & not fr': 'hello-ca-not-fr', + fr: 'bonjour-fr', + 'mobile-device': 'hello-mobile', + }, + { + key: 'marquee-hollow', + 'mobile-device & us': 'buy-now-mobile-us', + us: 'buy-now-us', + 'en-us': 'buy-now-en-us', + 'ca & not fr': 'buy-now-ca-not-fr', + fr: 'buy-now-fr', + 'mobile-device': 'buy-now-mobile', + }, + { + key: 'marquee-solid', + 'mobile-device & us': 'try-now-mobile-us', + us: 'try-now-us', + 'en-us': 'try-now-en-us', + 'ca & not fr': 'try-now-ca-not-fr', + fr: 'try-now-fr', + 'mobile-device': 'try-now-mobile', + }, + ], + secondManifestTest: [ + { + key: 'test-placeholder', + 'mobile-device & us': 'US Mobile Value', + us: 'value1-us', + 'en-us': 'new-en-us', + 'ca & not fr': 'value1-ca-not-fr', + fr: 'new-fr', + 'mobile-device': 'value1-mobile', + }, + { + key: 'test-placeholder2', + 'mobile-device & us': 'US Mobile Value2', + us: 'value2-us', + 'en-us': 'new2-en-us', + 'ca & not fr': 'value2-ca-not-fr', + fr: 'value2-fr', + 'mobile-device': 'value2-mobile', + }, + ], + keyTest: [ + { + key: 'test-placeholder', + 'mobile-device & us': 'US Mobile Value', + fr: 'value1-fr', + 'mobile-device': 'value1-mobile', + }, + { + key: 'test-placeholder2', + 'mobile-device & us': 'US Mobile Value2', + fr: 'value2-fr', + 'mobile-device': 'value2-mobile', + }, + { + key: 'marquee-headline', + 'mobile-device & us': 'hello US mobile', + fr: 'bonjour-fr', + 'mobile-device': 'hello-mobile', + }, + { + key: 'marquee-hollow', + 'mobile-device & us': 'buy-now-mobile-us', + fr: 'buy-now-fr', + 'mobile-device': 'buy-now-mobile', + }, + { + key: 'marquee-solid', + 'mobile-device & us': 'try-now-mobile-us', + fr: 'try-now-fr', + 'mobile-device': 'try-now-mobile', + }, + ], +}; + +export default placeholders; diff --git a/test/martech/attributes.test.js b/test/martech/attributes.test.js index 97593f80d3..263dec0b70 100644 --- a/test/martech/attributes.test.js +++ b/test/martech/attributes.test.js @@ -109,4 +109,13 @@ describe('Analytics', async () => { }, 20); expect(processedString).to.equal('Buy now'); }); + it('should process tracking labels with foreign locale and MEP placeholder', () => { + const translatedString = 'Comprar ahora'; + const processedString = processTrackingLabels(translatedString, { + locale: { ietf: 'es-ES' }, + analyticLocalization: { 'Comprar ahora': 'Buy now' }, + mep: { analyticLocalization: { 'Comprar ahora': 'Buy right now' } }, + }, 20); + expect(processedString).to.equal('Buy right now'); + }); });