resource-watch/widget

View on GitHub
app/src/services/relationships.service.js

Summary

Maintainability
C
1 day
Test Coverage
B
89%
const logger = require('logger');
const { RWAPIMicroservice } = require('rw-api-microservice-node');
const GetCollectionInvalidRequest = require('errors/getCollectionInvalidRequest.error');

const serializeObjToQuery = (obj) => Object.keys(obj).reduce((a, k) => {
    a.push(`${k}=${encodeURIComponent(obj[k])}`);
    return a;
}, []).join('&');

class RelationshipsService {

    /**
     * - Clones the query object
     * - Strips a few things that should not be passed over to other MSs
     * - Encodes query into a URL param format
     *
     * @param rawQuery
     * @returns {string}
     */
    static prepareAndFormatQuery(rawQuery) {
        const query = { ...rawQuery };

        const filterIncludesByEnv = query.filterIncludesByEnv ? query.filterIncludesByEnv : false;
        if (!filterIncludesByEnv) {
            delete query.env;
        }

        delete query.filterIncludesByEnv;
        delete query.includes;
        return serializeObjToQuery(query);
    }

    static appendUserFieldIfExists(userData, userObject, field) {
        if (userData[field]) userObject[field] = userData[field];
    }

    static formatWidgetOwner(userData, user) {
        const userObject = {};
        RelationshipsService.appendUserFieldIfExists(userData, userObject, 'name');
        RelationshipsService.appendUserFieldIfExists(userData, userObject, 'email');
        if (user && user.role === 'ADMIN') userObject.role = userData.role;
        return userObject;
    }

    static async getRelationships(widgets, includes, user, apiKey, query = {}) {
        logger.info(`Getting relationships of widgets: ${widgets}`);
        for (let i = 0; i < widgets.length; i++) {
            try {
                if (includes.indexOf('vocabulary') > -1) {
                    let uriQuery = RelationshipsService.prepareAndFormatQuery(query);
                    if (uriQuery.length > 0) {
                        uriQuery = `?${uriQuery}`;
                    }
                    const vocabularies = await RWAPIMicroservice.requestToMicroservice({
                        uri: `/v1/dataset/${widgets[i].dataset}/widget/${widgets[i]._id}/vocabulary${uriQuery}`,
                        method: 'GET',
                        json: true,
                        headers: {
                            'x-api-key': apiKey,
                        }
                    });
                    widgets[i].vocabulary = vocabularies.data;
                }
                if (includes.indexOf('user') > -1) {
                    const userData = await RWAPIMicroservice.requestToMicroservice({
                        uri: `/auth/user/find-by-ids`,
                        method: 'POST',
                        json: true,
                        body: {
                            ids: [widgets[i].userId]
                        },
                        version: false,
                        headers: {
                            'x-api-key': apiKey,
                        }
                    });

                    if (!userData.data[0]) {
                        logger.warn(`Tried to use find-by-ids to load info for user with id ${widgets[i].userId} but the following was returned: ${JSON.stringify(userData)}`);
                    } else {
                        widgets[i].user = RelationshipsService.formatWidgetOwner(userData.data[0], user);
                        logger.info('Widgets including user data', widgets.map((el) => el.toObject()));
                    }
                }
                if (includes.indexOf('metadata') > -1) {
                    const body = {
                        ids: [widgets[i].id],
                    };

                    if (query.env) {
                        body.env = query.env.split(',').map((elem) => elem.trim());
                    }
                    const metadata = await RWAPIMicroservice.requestToMicroservice({
                        uri: `/v1/dataset/${widgets[i].dataset}/widget/metadata/find-by-ids`,
                        method: 'POST',
                        json: true,
                        body,
                        headers: {
                            'x-api-key': apiKey,
                        }
                    });
                    widgets[i].metadata = metadata.data;
                }
            } catch (err) {
                logger.error(err);
            }
        }
        return widgets;
    }

    static async getCollections(ids, userId, apiKey) {
        logger.debug(`[RelationshipsService] getCollections for ids ${ids} and userID ${userId}.`);
        try {
            const result = await RWAPIMicroservice.requestToMicroservice({
                uri: `/v1/collection/find-by-ids`,
                method: 'POST',
                json: true,
                body: {
                    ids,
                    userId
                },
                headers: {
                    'x-api-key': apiKey,
                }
            });
            logger.debug(`[RelationshipsService] Result of getCollections: `, result);
            const collectionsWithWidgetResources = result.data
                .map((col) => col.attributes.resources.filter((res) => res.type === 'widget'));

            if (collectionsWithWidgetResources.length === 0) {
                return [];
            }

            return collectionsWithWidgetResources
                .reduce((pre, cur) => pre.concat(cur)).map((el) => el.id);
        } catch (e) {
            throw new GetCollectionInvalidRequest(e.message, e.statusCode || 500);
        }
    }

    static async getUsersWithRole(role, apiKey) {
        const body = await RWAPIMicroservice.requestToMicroservice({
            uri: `/auth/user/ids/${role}`,
            method: 'GET',
            json: true,
            version: false,
            headers: {
                'x-api-key': apiKey,
            }
        });
        logger.debug('User ids', body.data);
        return body.data;
    }

    static async getFavorites(app, userId, apiKey) {
        try {
            const result = await RWAPIMicroservice.requestToMicroservice({
                uri: `/v1/favourite/find-by-user`,
                method: 'POST',
                json: true,
                body: {
                    app,
                    userId
                },
                headers: {
                    'x-api-key': apiKey,
                }
            });
            logger.debug(result);
            return result.data.filter((fav) => fav.attributes.resourceType === 'widget').map((el) => el.attributes.resourceId);
        } catch (e) {
            throw new Error(e);
        }
    }

    static async getUsersInfoByIds(ids, apiKey) {
        logger.debug('Fetching all users\' information');
        const body = await RWAPIMicroservice.requestToMicroservice({
            uri: `/auth/user/find-by-ids`,
            method: 'POST',
            json: true,
            version: false,
            body: { ids },
            headers: {
                'x-api-key': apiKey,
            }
        });

        return body.data;
    }

}

module.exports = RelationshipsService;