diff --git a/static/js/formatters-internal.js b/static/js/formatters-internal.js index 85e1d1d88..f6fec79ae 100644 --- a/static/js/formatters-internal.js +++ b/static/js/formatters-internal.js @@ -566,3 +566,24 @@ export function getYoutubeUrl(videos = []) { : null; return youtubeVideoUrl; } + +/** + * construct a list of displayable category names based on given category ids from liveAPI + * and a mapping of category ids to names. + * + * @param {string[]} categoryIds category ids from liveAPI + * @param {Object[]} categoryMap mapping of category ids to names + * @param {string} categoryMap[].id id of a category entry + * @param {string} categoryMap[].category name of a category entry + * @returns {string[]} a list of category names + */ + export function getCategoryNames(categoryIds, categoryMap) { + if (!categoryIds || !categoryMap) { + return []; + } + return categoryIds.reduce((list, id) => { + const categoryEntry = categoryMap.find(category => category.id === id); + categoryEntry ? list.push(categoryEntry.category) : console.error(`Unable to find category name for id ${id}.`); + return list; + }, []); +} diff --git a/static/js/formatters.js b/static/js/formatters.js index 1d1084929..de2e58479 100644 --- a/static/js/formatters.js +++ b/static/js/formatters.js @@ -29,7 +29,8 @@ import { generateCTAFieldTypeLink, price, highlightField, - getYoutubeUrl + getYoutubeUrl, + getCategoryNames } from './formatters-internal.js'; import * as CustomFormatters from './formatters-custom.js'; @@ -62,7 +63,8 @@ let Formatters = { generateCTAFieldTypeLink, price, highlightField, - getYoutubeUrl + getYoutubeUrl, + getCategoryNames }; Formatters = Object.assign(Formatters, CustomFormatters); diff --git a/tests/static/js/formatters.js b/tests/static/js/formatters.js index 601a46cb3..1e2c6b0b3 100644 --- a/tests/static/js/formatters.js +++ b/tests/static/js/formatters.js @@ -153,4 +153,57 @@ describe('Formatters', () => { expect(actual).toEqual(expected); }); }); + + describe('getCategoryNames', () => { + const categoryMap = [ + { + "id": "1", + "category": "Neurology" + }, + { + "id": "2", + "category": "Dermatology" + }, + { + "id": "3", + "category": "Psychiatry" + }, + { + "id": "4", + "category": "Surgery" + } + ]; + + it('Handle undefined categoryIds and categoryMap', () => { + let categoryNames = Formatters.getCategoryNames(null, categoryMap); + expect(categoryNames).toEqual([]); + categoryNames = Formatters.getCategoryNames(['1'], null); + expect(categoryNames).toEqual([]); + }); + + it('return empty list for no matching category names', () => { + const categoryIds = ['5', '0']; + const consoleWarn = jest.spyOn(console, 'error') + .mockImplementation(); + const categoryNames = Formatters.getCategoryNames(categoryIds, categoryMap); + expect(categoryNames).toEqual([]); + expect(consoleWarn).toHaveBeenCalledTimes(2); + console.error.mockClear(); + }); + + it('return a list of matching category names', () => { + const categoryIds = ['1', '3']; + const categoryNames = Formatters.getCategoryNames(categoryIds, categoryMap); + expect(categoryNames).toEqual(['Neurology', 'Psychiatry']); + }); + + it('return a list of category names given non-matching and matching ids', () => { + const categoryIds = ['1', '10', '4']; + const consoleWarn = jest.spyOn(console, 'error') + .mockImplementation(); + const categoryNames = Formatters.getCategoryNames(categoryIds, categoryMap); + expect(categoryNames).toEqual(['Neurology', 'Surgery']); + expect(consoleWarn).toHaveBeenCalledTimes(1); + }); + }); });