diff --git a/package-lock.json b/package-lock.json index 350be3b..18e8ec7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@agility/content-fetch", - "version": "0.8.1", + "version": "0.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 756aba3..7ef422b 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,14 @@ { "name": "@agility/content-fetch", - "version": "0.8.2", + "version": "0.9.0", "description": "JavaScript library for the Agility Fetch API (node and browser)", "main": "dist/agility-content-fetch.node.js", "scripts": { "test": "nyc --reporter=html --reporter=text mocha --require @babel/register --recursive ./test/", "test-r": "nyc --reporter=html --reporter=text mocha --require @babel/register --recursive ./test/getUrlRedirections.tests.js", + "test-cl": "nyc --reporter=html --reporter=text mocha --require @babel/register --recursive ./test/getContentList.tests.js", + "test-ci": "nyc --reporter=html --reporter=text mocha --require @babel/register --recursive ./test/getContentItem.tests.js", + "test-pg": "nyc --reporter=html --reporter=text mocha --require @babel/register --recursive ./test/getPage.tests.js", "generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose", "build": "webpack --config webpack.config -p" }, diff --git a/src/methods/getContentItem.js b/src/methods/getContentItem.js index b6cffcf..ea33864 100644 --- a/src/methods/getContentItem.js +++ b/src/methods/getContentItem.js @@ -6,7 +6,8 @@ import { buildRequestUrlPath, buildAuthHeader } from '../utils' * @param {Object} requestParams - The paramters for the API request. * @param {number} requestParams.contentID - The contentID of the requested item in this language. * @param {string} requestParams.languageCode - The language code of the content you want to retrieve. - * @param {number} [requestParams.contentLinkDepth] - The depth, representing the levels in which you want linked content auto-resolved. Default is 1. + * @param {number} [requestParams.contentLinkDepth] - The depth, representing the levels in which you want linked content auto-resolved. Default is **1**. + * @param {boolean} [requestParams.expandAllContentLinks] - Whether or not to expand entire linked content references, includings lists and items that are rendered in the CMS as Grid or Link. Default is **false** * @returns {Promise} - Returns a content item object. * @example * @@ -37,7 +38,7 @@ function getContentItem(requestParams) { requestParams = {...defaultParams, ...requestParams}; const req = { - url: `/item/${requestParams.contentID}?contentLinkDepth=${requestParams.contentLinkDepth}`, + url: `/item/${requestParams.contentID}?contentLinkDepth=${requestParams.contentLinkDepth}&expandAllContentLinks=${requestParams.expandAllContentLinks}`, method: 'get', baseURL: buildRequestUrlPath(this.config, requestParams.languageCode), headers: buildAuthHeader(this.config), @@ -55,13 +56,16 @@ function validateRequestParams(requestParams) { throw new TypeError('You must include a contentID number in your request params.'); } else if(requestParams.contentLinkDepth && (isNaN(requestParams.contentLinkDepth) || requestParams.contentLinkDepth < 0)) { throw new TypeError('When specifying contentLinkDepth, it must be a number greater than 0.'); + } else if(requestParams.expandAllContentLinks && typeof requestParams.expandAllContentLinks !== 'boolean') { + throw new TypeError('ExpandAllContentLinks parameter must be a value of true or false'); } else { return; } } const defaultParams = { - contentLinkDepth: 1 + contentLinkDepth: 1, + expandAllContentLinks: false } export default getContentItem; diff --git a/src/methods/getContentList.js b/src/methods/getContentList.js index f5217b3..7463dad 100644 --- a/src/methods/getContentList.js +++ b/src/methods/getContentList.js @@ -6,10 +6,11 @@ import {buildPathUrl, buildRequestUrlPath, buildAuthHeader } from '../utils' * @param {Object} requestParams - The parameters for the API request. * @param {string} requestParams.referenceName - The unique reference name of the content list you wish to retrieve in the specified language. * @param {string} requestParams.languageCode - The language code of the content you want to retrieve. - * @param {number} [requestParams.contentLinkDepth] - The depth, representing the levels in which you want linked content auto-resolved. Default is 1. + * @param {number} [requestParams.contentLinkDepth] - The depth, representing the levels in which you want linked content auto-resolved. Default is **1**. + * @param {boolean} [requestParams.expandAllContentLinks] - Whether or not to expand entire linked content references, includings lists and items that are rendered in the CMS as Grid or Link. Default is **false** * @param {number} [requestParams.take] - The maximum number of items to retrieve in this request. Default is **10**. Maximum allowed is **50**. * @param {number} [requestParams.skip] - The number of items to skip from the list. Default is **0**. Used for implementing pagination. - * @param {string} [requestParams.sort] - The field to sort the results by. Example *fields.title* or *properties.modified*. + * @param {string} [requestParams.sort] - The field to sort the results by. Example **fields.title** or **properties.modified**. * @param {AgilityFetch.Types.SortDirection} [requestParams.direction] - The direction to sort the results by. * @param {Array.} [requestParams.filters] - The collection of filters to filter the results by. * @param {AgilityFetch.Types.FilterLogicOperator} [requestParams.filtersLogicOperator] - The logic operator to combine multiple filters. @@ -60,11 +61,13 @@ function getContentList(requestParams) { validateRequestParams(requestParams); + requestParams.referenceName = sanitizeReferenceName(requestParams.referenceName); + //merge default params with request params requestParams = {...defaultParams, ...requestParams}; const req = { - url: buildPathUrl("list", requestParams.referenceName, requestParams.skip, requestParams.take, requestParams.sort, requestParams.direction, requestParams.filters, requestParams.filtersLogicOperator, requestParams.contentLinkDepth), + url: buildPathUrl("list", requestParams.referenceName, requestParams.skip, requestParams.take, requestParams.sort, requestParams.direction, requestParams.filters, requestParams.filtersLogicOperator, requestParams.contentLinkDepth, requestParams.expandAllContentLinks), method: 'get', baseURL: buildRequestUrlPath(this.config, requestParams.languageCode), headers: buildAuthHeader(this.config), @@ -74,6 +77,10 @@ function getContentList(requestParams) { return this.makeRequest(req); } +function sanitizeReferenceName(referenceName) { + return referenceName.toLowerCase(); +} + function validateRequestParams(requestParams) { if(!requestParams.languageCode) { throw new TypeError('You must include a languageCode in your request params.') @@ -117,13 +124,16 @@ function validateRequestParams(requestParams) { } } else if (requestParams.filtersLogicOperator && requestParams.filtersLogicOperator.toLowerCase() !== 'and' && requestParams.filtersLogicOperator.toLowerCase() !== 'or') { throw new TypeError('FiltersLogicOperator parameter must have a value of "AND" or "OR"'); + } else if(requestParams.expandAllContentLinks && typeof requestParams.expandAllContentLinks !== 'boolean') { + throw new TypeError('ExpandAllContentLinks parameter must be a value of true or false'); } return true; } const defaultParams = { - contentLinkDepth: 1 + contentLinkDepth: 1, + expandAllContentLinks: false } export default getContentList; \ No newline at end of file diff --git a/src/methods/getPage.js b/src/methods/getPage.js index f963b60..b2cac9a 100644 --- a/src/methods/getPage.js +++ b/src/methods/getPage.js @@ -6,7 +6,8 @@ import { buildRequestUrlPath, buildAuthHeader } from '../utils' * @param {Object} requestParams - The parameters for the API request. * @param {number} requestParams.pageID - The unique page ID of the page you wish to retrieve in the current language. * @param {string} requestParams.languageCode - The language code of the content you want to retrieve. - * @param {number} [requestParams.contentLinkDepth] - The depth, representing the levels in which you want linked content auto-resolved. Default is 2. + * @param {boolean} [requestParams.expandAllContentLinks] - Whether or not to expand entire linked content references, includings lists and items that are rendered in the CMS as Grid or Link. Default is **false** + * @param {number} [requestParams.contentLinkDepth] - The depth, representing the levels in which you want linked content auto-resolved. Default is **2**. * @returns {Promise} - Returns a page item object. * @example * @@ -36,7 +37,7 @@ function getPage(requestParams) { requestParams = {...defaultParams, ...requestParams}; const req = { - url: `/page/${requestParams.pageID}?contentLinkDepth=${requestParams.contentLinkDepth}`, + url: `/page/${requestParams.pageID}?contentLinkDepth=${requestParams.contentLinkDepth}&expandAllContentLinks=${requestParams.expandAllContentLinks}`, method: 'get', baseURL: buildRequestUrlPath(this.config, requestParams.languageCode), headers: buildAuthHeader(this.config), @@ -51,13 +52,16 @@ function validateRequestParams(requestParams) { throw new TypeError('You must include a languageCode in your request params.') } else if(!requestParams.pageID) { throw new TypeError('You must include a pageID in your request params.'); + } else if(requestParams.expandAllContentLinks && typeof requestParams.expandAllContentLinks !== 'boolean') { + throw new TypeError('ExpandAllContentLinks parameter must be a value of true or false'); } else { return; } } const defaultParams = { - contentLinkDepth: 2 + contentLinkDepth: 2, + expandAllContentLinks: true } diff --git a/src/utils.js b/src/utils.js index c156166..e6206e3 100644 --- a/src/utils.js +++ b/src/utils.js @@ -19,7 +19,7 @@ function buildRequestUrlPath(config, languageCode) { return urlPath; } -function buildPathUrl(contentType, referenceName, skip, take, sort, direction, filters, filtersLogicOperator, contentLinkDepth) { +function buildPathUrl(contentType, referenceName, skip, take, sort, direction, filters, filtersLogicOperator, contentLinkDepth, expandAllContentLinks) { let url = `/${contentType}/${referenceName}?contentLinkDepth=${contentLinkDepth}&`; filtersLogicOperator = filtersLogicOperator ? ` ${filtersLogicOperator} ` : ' AND '; @@ -46,6 +46,11 @@ function buildPathUrl(contentType, referenceName, skip, take, sort, direction, f } url += '&'; } + + if(expandAllContentLinks) { + url += `expandAllContentLinks=${expandAllContentLinks}&`; + } + return url; } diff --git a/test/getContentItem.tests.js b/test/getContentItem.tests.js index 567de9c..65825ec 100644 --- a/test/getContentItem.tests.js +++ b/test/getContentItem.tests.js @@ -120,5 +120,63 @@ describe('getContentItem:', function() { done(); }) + it('should throw error if expandAllContentLinks is not true/false', function(done) { + expect(function() { + var api = createApiClient(); + api.getContentItem({ + contentID: 22, + languageCode: 'en-us', + expandAllContentLinks: 'something' + }) + .then(function(contentItem) { + assert.strictEqual(contentItem.contentID, 22); + done(); + }) + .catch(done); + }).to.throw( TypeError ); + done(); + }) + + it('should expand all content links when expandContentLinks are set to true', function(done) { + var api = createApiClient(); + api.getContentItem({ + contentID: 65, //item within listwithnestedcontentlinks + languageCode: 'en-us', + expandAllContentLinks: true + }) + .then(function(contentItem) { + assert.strictEqual(Array.isArray(contentItem.fields.posts), true); + done(); + }) + .catch(done); + }) + + it('should NOT expand all content links when expandContentLinks are set to false', function(done) { + var api = createApiClient(); + api.getContentItem({ + contentID: 65, //item within listwithnestedcontentlinks + languageCode: 'en-us', + expandAllContentLinks: false + }) + .then(function(contentItem) { + assert.strictEqual(Array.isArray(contentItem.fields.posts), false); + done(); + }) + .catch(done); + }) + + it('should NOT expand all content links when expandContentLinks is not set', function(done) { + var api = createApiClient(); + api.getContentItem({ + contentID: 65, //item within listwithnestedcontentlinks + languageCode: 'en-us', + }) + .then(function(contentItem) { + assert.strictEqual(Array.isArray(contentItem.fields.posts), false); + done(); + }) + .catch(done); + }) + }); diff --git a/test/getContentList.tests.js b/test/getContentList.tests.js index 9dacc08..c5f8fe8 100644 --- a/test/getContentList.tests.js +++ b/test/getContentList.tests.js @@ -302,11 +302,52 @@ describe('getContentList:', function() { filters: [{property: 'contentID', operator: api.types.FilterOperators.EQUAL_TO, value: '16'}, {property: 'properties.referenceName', operator: api.types.FilterOperators.LIKE, value: 'posts'}], filtersLogicOperator: api.types.FilterLogicOperators.AND }) - .then(function(contentList) { - assert.strictEqual(contentList.items[0].contentID, 16); - assert.strictEqual(contentList.items.length, 1); - done(); - }) - .catch(done); + .then(function(contentList) { + assert.strictEqual(contentList.items[0].contentID, 16); + assert.strictEqual(contentList.items.length, 1); + done(); + }) + .catch(done); }); + + it('should expand all content links when expandContentLinks are set to true', function(done) { + var api = createApiClient(); + api.getContentList({ + referenceName: 'listwithnestedcontentlink', + languageCode: 'en-us', + expandAllContentLinks: true + }) + .then(function(contentList) { + assert.strictEqual(Array.isArray(contentList.items[0].fields.posts), true); + done(); + }) + .catch(done); + }) + + it('should NOT expand all content links when expandContentLinks are set to false', function(done) { + var api = createApiClient(); + api.getContentList({ + referenceName: 'listwithnestedcontentlink', + languageCode: 'en-us', + expandAllContentLinks: false + }) + .then(function(contentList) { + assert.strictEqual(Array.isArray(contentList.items[0].fields.posts), false); + done(); + }) + .catch(done); + }) + + it('should NOT expand all content links when expandContentLinks is not set at all', function(done) { + var api = createApiClient(); + api.getContentList({ + referenceName: 'listwithnestedcontentlink', + languageCode: 'en-us' + }) + .then(function(contentList) { + assert.strictEqual(Array.isArray(contentList.items[0].fields.posts), false); + done(); + }) + .catch(done); + }) }); \ No newline at end of file diff --git a/test/getPage.tests.js b/test/getPage.tests.js index dc2635c..18dd091 100644 --- a/test/getPage.tests.js +++ b/test/getPage.tests.js @@ -73,5 +73,21 @@ import { createApiClient, createPreviewApiClient, createCatchedApiClient } from }).to.throw( TypeError ); done(); }) + + it('should retrieve a page and expand all content links when expandAllContentLink is set to true', function(done) { + var api = createApiClient(); + api.getPage({ + pageID: 2, + languageCode: 'en-us', + expandAllContentLinks: true + }) + .then(function(page) { + assert.strictEqual(Array.isArray(page.zones.MainContentZone[2].item.fields.posts), true); + done(); + }) + .catch(done); + }) + + }) \ No newline at end of file