All files / src/menu menu.js

95.56% Statements 43/45
100% Branches 24/24
100% Functions 11/11
95.35% Lines 41/43

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86      5x 5x         5x       92x 92x 92x 92x       1x 1x 1x 1x                 1x 1x       1x 1x   1x 1x 1x                 3x 3x 3x 2x 1x 9x 9x 9x 9x 9x 9x 9x   1x 3x 3x 3x 6x   3x 3x   1x   1x       1x 1x          
import toQueryString from '../utils/toQueryString';
import waitForElementToExist from '../utils/waitForElementToExist';
 
const VYBE_API_ROOT = "http://merch.api.vybe.com/api/navigation";
const API = Object.freeze({
    GET_LIVE_BY_SITE:  `${VYBE_API_ROOT}/getlivebysite`
});
 
// Issue #98
const TMP_URL_FIX = "http://admin.preview.vybe.com/upload/image/";
 
class Menu {
    constructor(options) {
        this._tracking = options._tracking;
        this._outputMenu = this._outputMenu.bind(this);
        this.sentry = options.sentry;
        Object.assign(this, options);
    }
 
    init(options) {
        try {
            Object.assign(this, options);
            this.fetchMenu()
            .then(() => waitForElementToExist(this.container))
            .then(this._outputMenu);
        }
        catch (err) {
            this.sentry.captureException(err);
        }
    }
 
    fetchMenu() {
        try {
            const qs = toQueryString({
                token: this.token,
                siteName: encodeURI(this.siteName)
            });            
            return fetch(`${API.GET_LIVE_BY_SITE}?${qs}`)
                .then(response => response.json())
                .then(json => {
                    this.menu = json;
                    this._tracking.set(json.trackingData);
                    this._tracking.track("event", "Menu", "Loaded");
            })
        }
        catch (err) {
            this.sentry.captureException(err);
        }
    }
            
    _outputMenu() {
        try {
            const container = document.querySelector(this.container);
            if (container) {
                if (this.menu.navigationTabs === null) {return};        
                const menuItemHtml = data => {
                    let html = data.image && data.image !== "" ? `<img class="v-menu__img" src="${TMP_URL_FIX}${data.image}" alt="${data.title}">` : data.title;
                    html = data.bold ? `<strong>${html}</strong>` : html; //Font styling
                    html = data.italic ? `<em>${html}</em>` : html;
                    html = data.underline ? `<u>${html}</u>` : html;
                    html = data.url ? `<a class="v-menu__link" href="${data['url']}">${html}</a>` : html;
                    html = data.isHeader ? `<h3>${html}</h3>` : html;
                    return html;
                };
                let output = this.menu.navigationTabs.reduce((html, item) => {
                    html += `<li class="v-menu__item"><h2>${menuItemHtml(item)}</h2>`;
                    html += item.navigationColumns.length > 0 ? '<div>' : '';
                    item.navigationColumns.length && (
                        html += item.navigationColumns.reduce((a, b) => a += `<ul class="v-menu__sub-menu">${b.navigationLinkItems.reduce((c, d) => c += `<li class="v-menu__item">${menuItemHtml(d)}</li>`, '')}</ul>`,'')
                    );
                    html += item.navigationColumns.length > 0 ? '</div>' : '' + '</li>';
                    return html;
                },'');    
                container.innerHTML = `<h1 class="v-hidden">Navigation</h1><ul class="v-menu">${output}</ul></nav>`;
            } else {
                throw Error('Unable to find menu element');
            }
        }
        catch (err) {
            this.sentry.captureException(err);
            throw Error(err);
        }
    }
}
 
export default Menu;