Skip to content

Commit

Permalink
MWPW-155385: Added unit tests for personalization
Browse files Browse the repository at this point in the history
  • Loading branch information
zagi25 committed Aug 13, 2024
1 parent b8ba74c commit b8371e6
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 14 deletions.
21 changes: 8 additions & 13 deletions edsdme/scripts/personalization.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
partnerIsSignedIn,
getPartnerDataCookieObject,
signedInNonMember,
isReseller ,
isReseller,
getNodesByXPath
}
from './utils.js';

Expand All @@ -16,6 +17,7 @@ const PERSONALIZATION_MARKER = 'partner-personalization';
const PROGRAM = getCurrentProgramType();
const PARTNER_LEVEL = getPartnerDataCookieValue(PROGRAM, 'level');
const COOKIE_OBJECT = getPartnerDataCookieObject(PROGRAM);

const PERSONALIZATION_CONDITIONS = {
'partner-not-member': signedInNonMember(),
'partner-not-signed-in': !partnerIsSignedIn(),
Expand All @@ -24,22 +26,15 @@ const PERSONALIZATION_CONDITIONS = {
'partner-level': (level) => PARTNER_LEVEL === level,
};

export function getNodesByXPath(query, context = document) {
const nodes = [];
const xpathResult = document.evaluate(query, context);
let current = xpathResult?.iterateNext();
while (current) {
nodes.push(current);
current = xpathResult.iterateNext();
}
return nodes;
}

function personalizePlaceholders(placeholders, context = document) {
Object.entries(placeholders).forEach(([key, value]) => {
const placeholderValue = COOKIE_OBJECT[key];
getNodesByXPath(value, context).forEach((el) => {
if (!placeholderValue) el.remove();
if (!placeholderValue) {
el.remove();
return;
}
el.textContent = el.textContent.replace(`$${key}`, placeholderValue);
});
});
Expand Down Expand Up @@ -80,11 +75,11 @@ function hideSections(page) {

function personalizePage(page) {
const blocks = Array.from(page.getElementsByClassName(PERSONALIZATION_MARKER));
hideSections(page);
blocks.forEach((el) => {
const conditions = Object.values(el.classList);
hideElement(el, conditions);
});
hideSections(page);
}

export function applyPagePersonalization() {
Expand Down
1 change: 0 additions & 1 deletion edsdme/scripts/scripts.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { setLibs, redirectLoggedinPartner, updateIMSConfig, preloadResources, getRenewBanner } from './utils.js';
import { applyPagePersonalization } from './personalization.js';
import { setLibs, redirectLoggedinPartner, updateIMSConfig, preloadResources, getRenewBanner, updateNavigation, updateFooter } from './utils.js';

Expand Down
11 changes: 11 additions & 0 deletions edsdme/scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -397,3 +397,14 @@ export function updateFooter(locales) {
const footerLoggedIn = getMetadataContent('footer-loggedin-source');
footerMeta.content = footerLoggedIn ?? `${prefix}/edsdme/partners-shared/loggedin-footer`;
}

export function getNodesByXPath(query, context = document) {
const nodes = [];
const xpathResult = document.evaluate(query, context);
let current = xpathResult?.iterateNext();
while (current) {
nodes.push(current);
current = xpathResult.iterateNext();
}
return nodes;
}
114 changes: 114 additions & 0 deletions test/scripts/mocks/personalization.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<main>
<div>
<div class="marquee">
<div>
<div data-valign="middle">
<picture>
<source type="image/webp" srcset="./media_1b2111891fc6836011dc3d527c6999c59e792ed70.png?width=2000&#x26;format=webply&#x26;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_1b2111891fc6836011dc3d527c6999c59e792ed70.png?width=750&#x26;format=webply&#x26;optimize=medium">
<source type="image/png" srcset="./media_1b2111891fc6836011dc3d527c6999c59e792ed70.png?width=2000&#x26;format=png&#x26;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="" src="./media_1b2111891fc6836011dc3d527c6999c59e792ed70.png?width=750&#x26;format=png&#x26;optimize=medium" width="750" height="375">
</picture>
</div>
</div>
<div>
<div data-valign="middle">
<p>
<picture>
<source type="image/webp" srcset="./media_14fca9c1d62860abc54e560109211d31d00b7fcd3.png?width=2000&#x26;format=webply&#x26;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_14fca9c1d62860abc54e560109211d31d00b7fcd3.png?width=750&#x26;format=webply&#x26;optimize=medium">
<source type="image/png" srcset="./media_14fca9c1d62860abc54e560109211d31d00b7fcd3.png?width=2000&#x26;format=png&#x26;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="" src="./media_14fca9c1d62860abc54e560109211d31d00b7fcd3.png?width=750&#x26;format=png&#x26;optimize=medium" width="154" height="150">
</picture>
</p>
<h1 id="heading-xl-marquee-standard-medium-left">Heading XL Marquee standard medium left</h1>
<h4 id="welcome-firstname">Welcome $firstName</h4>
<p>Body M Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation.</p>
<p><em><a href="https://www.adobe.com/">Lorem ipsum</a></em> <strong><a href="https://www.adobe.com/">Learn more</a></strong> <a href="https://www.adobe.com/">Text link</a></p>
</div>
<div data-valign="middle">
<picture>
<source type="image/webp" srcset="./media_1168e12a35e1cecd1eb49bddbdb174ec21ffa152e.png?width=2000&#x26;format=webply&#x26;optimize=medium" media="(min-width: 600px)">
<source type="image/webp" srcset="./media_1168e12a35e1cecd1eb49bddbdb174ec21ffa152e.png?width=750&#x26;format=webply&#x26;optimize=medium">
<source type="image/png" srcset="./media_1168e12a35e1cecd1eb49bddbdb174ec21ffa152e.png?width=2000&#x26;format=png&#x26;optimize=medium" media="(min-width: 600px)">
<img loading="lazy" alt="" src="./media_1168e12a35e1cecd1eb49bddbdb174ec21ffa152e.png?width=750&#x26;format=png&#x26;optimize=medium" width="600" height="300">
</picture>
</div>
</div>
</div>
</div>
<div>
<div class="text full-width partner-personalization partner-not-signed-in">
<div>
<div data-valign="middle">
<h3 id="partner-not-signed-in"><strong>Partner NOT SIGNED IN</strong></h3>
<p>Featuring over 600,000 hand-picked stock photos and graphics, curated from the world’s leading photographers, illustrators, and agencies. Our Premium collection is perfect for organizations looking for authentic, high-quality commercial content, and easy licensing plans.</p>
<p><a href="https://stock.adobe.com/premium">Explore the premium collection</a></p>
<p><strong><a href="http://adobe.com">Join Now</a></strong></p>
</div>
</div>
</div>
<div class="text full-width partner-personalization partner-not-member">
<div>
<div data-valign="middle">
<h3 id="partner-non-member"><strong>Partner NON MEMBER</strong></h3>
<p>Featuring over 600,000 hand-picked stock photos and graphics, curated from the world’s leading photographers, illustrators, and agencies. Our Premium collection is perfect for organizations looking for authentic, high-quality commercial content, and easy licensing plans.</p>
<p><a href="https://stock.adobe.com/premium">Explore the premium collection</a></p>
<p><strong><a href="http://adobe.com">Join Now</a></strong></p>
</div>
</div>
</div>
<div class="text full-width partner-personalization partner-all-levels">
<div>
<div data-valign="middle">
<h3 id="member"><strong>MEMBER</strong></h3>
<p>Featuring over 600,000 hand-picked stock photos and graphics, curated from the world’s leading photographers, illustrators, and agencies. Our Premium collection is perfect for organizations looking for authentic, high-quality commercial content, and easy licensing plans.</p>
</div>
</div>
</div>
</div>
<div>
<div class="text full-width partner-personalization partner-level-gold">
<div>
<div data-valign="middle">
<h3 id="partner-gold"><strong>Partner GOLD</strong></h3>
<p>Featuring over 600,000 hand-picked stock photos and graphics, curated from the world’s leading photographers, illustrators, and agencies. Our Premium collection is perfect for organizations looking for authentic, high-quality commercial content, and easy licensing plans.</p>
</div>
</div>
</div>
</div>
<div>
<div class="text full-width partner-personalization partner-level-platinum">
<div>
<div data-valign="middle">
<h3 id="partner-platinum"><strong>Partner Platinum</strong></h3>
<p>Featuring over 600,000 hand-picked stock photos and graphics, curated from the world’s leading photographers, illustrators, and agencies. Our Premium collection is perfect for organizations looking for authentic, high-quality commercial content, and easy licensing plans.</p>
<p><a href="https://stock.adobe.com/premium">Explore the premium collection</a></p>
</div>
</div>
</div>
<div class="section-metadata">
<div>
<div data-valign="middle">style</div>
<div data-valign="middle">partner-personalization, partner-level-platinum</div>
</div>
</div>
</div>
<div>
<div id="platinum-section" class="text full-width">
<div>
<div data-valign="middle">
<h3 id="partner-platinum-section"><strong>Partner Platinum section</strong></h3>
<p>Featuring over 600,000 hand-picked stock photos and graphics, curated from the world’s leading photographers, illustrators, and agencies. Our Premium collection is perfect for organizations looking for authentic, high-quality commercial content, and easy licensing plans.</p>
<p><a href="https://stock.adobe.com/premium">Explore the premium collection</a></p>
</div>
</div>
</div>
<div class="section-metadata">
<div>
<div data-valign="middle">style</div>
<div data-valign="middle">partner-personalization, partner-level-platinum</div>
</div>
</div>
</div>
</main>
158 changes: 158 additions & 0 deletions test/scripts/personalization.jest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/**
* @jest-environment jsdom
*/
import path from 'path';
import fs from 'fs';

const PERSONALIZATION_HIDE_CLASS = 'personalization-hide';

function importModules() {
const utils = require('../../edsdme/scripts/utils.js');
const placeholderElement = document.querySelector('#welcome-firstname');
jest.spyOn(utils, 'getNodesByXPath').mockImplementation(() => [placeholderElement]);
const { applyPagePersonalization } = require('../../edsdme/scripts/personalization.js');

return applyPagePersonalization;
}

describe('Test utils.js', () => {
beforeEach(() => {
jest.clearAllMocks();
window = Object.create(window);
Object.defineProperty(window, 'location', {
value: {
pathname:'/channelpartners',
},
writable: true
});
document.body.innerHTML = fs.readFileSync(
path.resolve(__dirname, './mocks/personalization.html'),
'utf8'
);
document.cookie = 'partner_data=';
});
afterEach(() => {
document.body.innerHTML = '';
});
it('Populate placeholder if user is a member', () => {
jest.isolateModules(() => {
const cookieObject = {
CPP: {
status: 'MEMBER',
firstName: 'Test user'
}
};
document.cookie = `partner_data=${JSON.stringify(cookieObject)}`;
const applyPagePersonalization = importModules();
applyPagePersonalization();
const placeholderElementAfter = document.querySelector('#welcome-firstname');
expect(placeholderElementAfter.textContent.includes(cookieObject.CPP.firstName)).toBe(true);
});
});
it('Remove placeholder if user is not a member', () => {
jest.isolateModules(() => {
const cookieObject = {
SPP: {
status: 'MEMBER',
firstName: 'Test use'
}
};
document.cookie = `partner_data=${JSON.stringify(cookieObject)}`;
const applyPagePersonalization = importModules();
applyPagePersonalization();
const placeholderElementAfter = document.querySelector('#welcome-firstname');
expect(placeholderElementAfter).toBe(null);
});
});
it('Show partner-not-signed-in block', () => {
jest.isolateModules(() => {
const applyPagePersonalization = importModules();
applyPagePersonalization();
const notSignedInBlock = document.querySelector('.partner-not-signed-in');
expect(notSignedInBlock.classList.contains(PERSONALIZATION_HIDE_CLASS)).toBe(false);
});
});

it('Show partner-not-member block', () => {
jest.isolateModules(() => {
const cookieObject = {
SPP: {
status: 'MEMBER',
firstName: 'Test use'
}
};
document.cookie = `partner_data=${JSON.stringify(cookieObject)}`;
const applyPagePersonalization = importModules();
applyPagePersonalization();
const notMemberBlock = document.querySelector('.partner-not-member');
expect(notMemberBlock.classList.contains(PERSONALIZATION_HIDE_CLASS)).toBe(false);
});
});
it('Show partner-all-levels block', () => {
jest.isolateModules(() => {
const cookieObject = {
CPP: {
status: 'MEMBER',
firstName: 'Test use',
level: 'Gold'
}
};
document.cookie = `partner_data=${JSON.stringify(cookieObject)}`;
const applyPagePersonalization = importModules();
applyPagePersonalization();
const allLevelsBlock = document.querySelector('.partner-all-levels');
expect(allLevelsBlock.classList.contains(PERSONALIZATION_HIDE_CLASS)).toBe(false);
});
});
it('Show partner-level-gold block', () => {
jest.isolateModules(() => {
const cookieObject = {
CPP: {
status: 'MEMBER',
firstName: 'Test use',
level: 'Gold'
}
};
document.cookie = `partner_data=${JSON.stringify(cookieObject)}`;
const applyPagePersonalization = importModules();
applyPagePersonalization();
const goldBlock = document.querySelector('.partner-level-gold');
expect(goldBlock.classList.contains(PERSONALIZATION_HIDE_CLASS)).toBe(false);
});
});
it('Show partner-level-platinum but don\'t show partner-level-gold block', () => {
jest.isolateModules(() => {
const cookieObject = {
CPP: {
status: 'MEMBER',
firstName: 'Test use',
level: 'Platinum'
}
};
document.cookie = `partner_data=${JSON.stringify(cookieObject)}`;
const applyPagePersonalization = importModules();
applyPagePersonalization();
const goldBlock = document.querySelector('.partner-level-gold');
const platinumBlock = document.querySelector('.partner-level-platinum');
expect(platinumBlock.classList.contains(PERSONALIZATION_HIDE_CLASS)).toBe(false);
expect(goldBlock.classList.contains(PERSONALIZATION_HIDE_CLASS)).toBe(true);
});
});
it('Show partner-level-platinum section', () => {
jest.isolateModules(() => {
const cookieObject = {
CPP: {
status: 'MEMBER',
firstName: 'Test use',
level: 'Platinum'
}
};
document.cookie = `partner_data=${JSON.stringify(cookieObject)}`;
const applyPagePersonalization = importModules();
applyPagePersonalization();
const platinumBlock = document.querySelector('#platinum-section');
expect(platinumBlock.classList.contains(PERSONALIZATION_HIDE_CLASS)).toBe(false);
});
});
});

0 comments on commit b8371e6

Please sign in to comment.