Skip to content

Commit

Permalink
MWPW-138577: Global footer logging (#1514)
Browse files Browse the repository at this point in the history
* feat: footer unit tests

* feat: unit tests for mobile, tablet, and wide screen layouts

* hotfix

* optimizing

* feat: added lana logging to the global-footer

* hotfix

* hotfix

* feat: added unit tests for footer logging

* Improving Code Readability

* hotfix

* hotfix: added link for favicon

* hotfix

* hotfix

* increased branches code coverage

* hotfixes

* increased branches code coverage for global footer

* unit tests for global footer logs

* fixed rebase error

* fixed sinon sub error on global footer tests

* mocked ims for gnav.js unit tests

* hotfix

* optimizing

* added unit test for logs when footer cannot be instantiated

* optimizing

---------

Co-authored-by: Narcis Radu <github@narcisradu.ro>
Co-authored-by: Blaine Gunn <Blainegunn@gmail.com>
  • Loading branch information
3 people authored Dec 4, 2023
1 parent 14295ec commit 33150d4
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 9 deletions.
26 changes: 19 additions & 7 deletions libs/blocks/global-footer/global-footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
getAnalyticsValue,
loadBaseStyles,
yieldToMain,
lanaLog,
logErrorFor,
} from '../global-navigation/utilities/utilities.js';

import { replaceKey, replaceText } from '../../features/placeholders.js';
Expand All @@ -36,7 +38,7 @@ class Footer {
this.init();
}

init = async () => {
init = () => logErrorFor(async () => {
// We initialize the footer decoration logic when either 3s have passed
// OR when the footer element is close to coming into view
let decorationTimeout;
Expand All @@ -61,14 +63,14 @@ class Footer {
observer.disconnect();
this.decorateContent();
}, CONFIG.delays.decoration);
};
}, 'Error in global footer init', 'errorType=error,module=global-footer');

decorateContent = async () => {
decorateContent = () => logErrorFor(async () => {
// Fetch footer content
this.body = await this.fetchContent();

// TODO: log to LANA if Footer content could not be found
if (!this.body) return;

// TODO: revisit region picker and social links decoration logic
const regionAnchor = this.body.querySelector('.region-selector a');
if (regionAnchor?.href) {
Expand Down Expand Up @@ -101,10 +103,18 @@ class Footer {
this.footerEl.setAttribute('daa-lh', `gnav|${getExperienceName()}|footer|${document.body.dataset.mep}`);

this.footerEl.append(this.elements.footer);
};
}, 'Failed to decorate footer content', 'errorType=error,module=global-footer');

fetchContent = async () => {
const resp = await fetch(`${this.contentUrl}.plain.html`);

if (!resp.ok) {
lanaLog({
message: `Failed to fetch footer content; content url: ${this.contentUrl}, status: ${resp.statusText}`,
tags: 'errorType=warn,module=global-footer',
});
}

const html = await resp.text();

if (!html) return null;
Expand All @@ -114,7 +124,7 @@ class Footer {
try {
return new DOMParser().parseFromString(parsedHTML, 'text/html').body;
} catch (e) {
// TODO: log to LANA if Footer could not be instantiated
lanaLog({ message: 'Footer could not be instantiated', tags: 'errorType=error,module=global-footer' });
return null;
}
};
Expand Down Expand Up @@ -153,6 +163,7 @@ class Footer {

loadIcons = async () => {
const file = await fetch(`${base}/blocks/global-footer/icons.svg`);

const content = await file.text();
const elem = toFragment`<div class="feds-footer-icons">${content}</div>`;
this.footerEl.append(elem);
Expand Down Expand Up @@ -195,7 +206,8 @@ class Footer {
try {
url = new URL(regionSelector.href);
} catch (e) {
// TODO: Log to Lana if URL could not be created
lanaLog({ message: `Could not create URL for region picker; href: ${regionSelector.href}`, tags: 'errorType=error,module=global-footer' });
throw e;
}

if (!url) return this.elements.regionPicker;
Expand Down
70 changes: 68 additions & 2 deletions test/blocks/global-footer/global-footer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import fetchedFooter from './mocks/fetched-footer.js';
import icons from './mocks/icons.js';
import { isElementVisible, mockRes } from '../global-navigation/test-utilities.js';
import placeholders from '../global-navigation/mocks/placeholders.js';
import { logErrorFor } from '../../../libs/blocks/global-navigation/utilities/utilities.js';

describe('global footer', () => {
let clock = null;
Expand All @@ -41,8 +42,7 @@ describe('global footer', () => {
});

afterEach(() => {
clock.restore();
window.fetch.restore();
sinon.restore();
document.body.innerHTML = '';
});

Expand Down Expand Up @@ -272,4 +272,70 @@ describe('global footer', () => {
}
});
});

describe('LANA logging tests', () => {
beforeEach(async () => {
window.lana.log = sinon.spy();
});

it('should send log on error', async () => {
const erroneousFunction = async () => {
throw new Error('error');
};

const logMessage = 'test message';
const logTags = 'errorType=error,module=global-footer';
await logErrorFor(erroneousFunction, logMessage, logTags);

expect(window.lana.log.calledOnce).to.be.true;

const firstCallArguments = window.lana.log.getCall(0).args;

expect(firstCallArguments[0].includes(logMessage)).to.equal(true);
expect(firstCallArguments[1].tags === logTags).to.equal(true);
});

it('should send log when footer cannot be fetched', async () => {
window.fetch.restore();
stub(window, 'fetch').callsFake((url) => {
if (url.includes('/footer')) {
return mockRes({
payload: null,
ok: false,
status: 400,
});
}
if (url.includes('/placeholders')) return mockRes({ payload: placeholders });
if (url.includes('icons.svg')) return mockRes({ payload: icons });
return null;
});
await createFullGlobalFooter({ waitForDecoration: false });
await clock.runAllAsync();
expect(window.lana.log.getCalls().find((c) => c.args[0].includes('Failed to fetch footer content')));
expect(window.lana.log.getCalls().find((c) => c.args[1].tags.includes('errorType=warn,module=global-footer')));
});

it('should send log when could not create URL for region picker', async () => {
const globalFooter = await createFullGlobalFooter({ waitForDecoration: true });
sinon.restore();
stub(window, 'URL').callsFake(() => {
throw new Error('mocked error');
});
try {
await globalFooter.decorateRegionPicker();
} catch (e) {
// should throw error
}
expect(window.lana.log.getCalls().find((c) => c.args[0].includes('Could not create URL for region picker')));
expect(window.lana.log.getCalls().find((c) => c.args[1].tags.includes('errorType=error,module=global-footer')));
});

it('should send log when footer cannot be instantiated ', async () => {
sinon.stub(window, 'DOMParser').callsFake(() => ({ parseFromString: sinon.stub().throws(new Error('Parsing error')) }));
await createFullGlobalFooter({ waitForDecoration: false });
await clock.runAllAsync();
expect(window.lana.log.getCalls().find((c) => c.args[0].includes('Footer could not be instantiated')));
expect(window.lana.log.getCalls().find((c) => c.args[1].tags.includes('errorType=error,module=global-footer')));
});
});
});

0 comments on commit 33150d4

Please sign in to comment.