all files / api/toJSON/ article.js

100% Statements 49/49
100% Branches 30/30
100% Functions 2/2
100% Lines 48/48
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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127      15×                                                                                                 20×     21× 21×   21×           20× 20×   20×   20×   20×           20×     20× 19×               19× 19× 19× 19× 19× 19× 19× 19× 19× 19×   19×    
'use strict';
 
const R = require('ramda');
const tz = require('timezone/loaded');
let createSection = require('./section');
let createArticleContent = require('./articleContent');
let getLastUpdated = require('./getLastUpdated');
let createLeadMedia = require('./leadMedia');
 
function createNews(article) {
    return {
        data: {
            type: article.type,
            id: article.escenic_id,
            attributes: {
                createdDate: tz(article.created_date, '%Y-%m-%dT%H:%M:%S.%3N%^z', 'UTC'),
                publishedDate: tz(article.published_date, '%Y-%m-%dT%H:%M:%S.%3N%^z', 'UTC'),
                state: article.state,
                primaryTag: article.primary_tag,
                advertorial: article.sub_type === 'advertorial',
                sponsored: article.sub_type === 'sponsored',
                subtype: R.find(R.equals(article.sub_type), ['sponsored', 'advertorial']) || null,
                exclude: R.defaultTo(false, article.exclude_mobile),
                comments: R.defaultTo(false, article.comments),
                webview: article.interactive,
                heading: article.heading,
                socialHeadline: article.social_headline,
                leadText: article.lead_text
            },
            links: {
                ownerUrl: article.owner_url || void 0
            }
        }
    };
}
 
function createLiveEvent(article) {
    const url_home_section = R.path(['home_section', 'url'], article);
    const url = url_home_section.replace('http:', 'https:');
    const publication = R.path(['home_section', 'publication', 'name'], article);
    return {
        data: {
            type: article.type,
            id: article.escenic_id,
            attributes: {
                createdDate: tz(article.created_date, '%Y-%m-%dT%H:%M:%S.%3N%^z', 'UTC'),
                publishedDate: tz(article.published_date, '%Y-%m-%dT%H:%M:%S.%3N%^z', 'UTC'),
                state: article.state,
                primaryTag: article.primary_tag,
                advertorial: article.sub_type === 'advertorial',
                sponsored: article.sub_type === 'sponsored',
                comments: R.defaultTo(false, article.comments),
                subtype: R.find(R.equals(article.sub_type), ['sponsored', 'advertorial']) || null,
                webview: true,
                title: article.title
            },
            links: {
                ownerUrl: article.owner_url || void 0,
                liveEventEntriesUrl: `${url}${article.file_name}/embedded-webview/${publication}-${article.escenic_id}`
            }
        }
    };
}
 
const isNewsOrOpinion = article => R.either(R.propEq('type', 'news'), R.propEq('type', 'opinion'))(article);
 
module.exports = R.curry((config, tuple) => {
 
    const article = tuple[1];
    const type = article['type'];
 
    if(type !== 'live-event' && R.isNil(article.heading)) {
        throw {
            status: 'BadRequestError',
            message: `No heading found in article ${article.id}`
        };
    }
 
    let included, homeSection, leadMedia;
    homeSection = {};
 
    const appsArticle = R.ifElse(isNewsOrOpinion, createNews, createLiveEvent)(article);
 
    let lastModifiedDate = R.path(["last_modified_date"], article);
 
    if (R.has('article_contents', article)) {
        const contents = R.map(contentItem => {
            return createArticleContent(config.imageDimensions, contentItem, article.home_section, article.file_name);
        }, article.article_contents);
 
        const filteredContents = R.reject(R.isNil, contents);
 
        appsArticle.data.attributes.webview = type === 'live-event' || R.any(R.pipe(R.head, R.has("webview")), filteredContents);
        lastModifiedDate = getLastUpdated(lastModifiedDate, contents);
        included = filteredContents.map(R.last);
    }
 
    if(R.has('article_relations', article) && article.article_relations.length > 0) {
        const leadMediaTuple = createLeadMedia(config.imageDimensions, article.article_relations);
        lastModifiedDate = getLastUpdated(lastModifiedDate, Array.of(leadMediaTuple));
        leadMedia = leadMediaTuple ? leadMediaTuple[1]: null;
    }
 
    if (R.has('home_section', article) && article.home_section) {
        homeSection = createSection(article.home_section);
    } else {
        throw {
            status: 'NotFoundError',
            message: `Section ${article.home_section_id} not available`,
            type: 'SectionNotFound'
        };
    }
 
    appsArticle.included = included || [];
    appsArticle.data.attributes.homeSection = R.pick(['name'], homeSection);
    appsArticle.data.attributes.authors = [];
    appsArticle.data.attributes.tags = [];
    appsArticle.data.attributes.leadMedia = leadMedia || null;
    appsArticle.data.links.url = `${homeSection.url}${article.file_name}?widgetId=${config.widgetIds.online}`;
    appsArticle.data.links.offlineUrl = `${homeSection.url}${article.file_name}?widgetId=${config.widgetIds.offline}&service=tablet`;
    appsArticle.data.attributes.lastModifiedDate = lastModifiedDate;
    tuple[0].file_name = article.file_name;
    tuple[0].section = article.home_section;
 
    return [tuple[0], appsArticle];
});