From 5b5f1edb2203acd9ad20dce2615c2813029a8050 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Fri, 11 Nov 2016 12:17:01 +0100 Subject: [PATCH] Moved applyDefaults function and related code to actions (where it belong). - Moved applyDefaults + related code - Added tests for /actions/config.js - Fixed some ESLint errors --- src/actions/__tests__/config.spec.js | 61 +++++++++++++++++ src/actions/config.js | 76 ++++++++++++++-------- src/reducers/__tests__/collections.spec.js | 19 ++++-- src/reducers/config.js | 18 +---- 4 files changed, 127 insertions(+), 47 deletions(-) create mode 100644 src/actions/__tests__/config.spec.js diff --git a/src/actions/__tests__/config.spec.js b/src/actions/__tests__/config.spec.js new file mode 100644 index 00000000..26de726d --- /dev/null +++ b/src/actions/__tests__/config.spec.js @@ -0,0 +1,61 @@ +import * as config from '../config'; + +describe('config', () => { + describe('applyDefaults', () => { + it('should throw if media_folder is not defined in config', () => { + expect(() => { + config.applyDefaults({ foo: 'bar' }); + }).toThrowError('Config: `media_folder` setting could not be found in config.'); + }); + + it('should set publish_mode if not set', () => { + expect(config.applyDefaults({ + foo: 'bar', + media_folder: 'path/to/media', + })).toEqual({ + foo: 'bar', + publish_mode: 'simple', + media_folder: 'path/to/media', + public_folder: '/path/to/media', + }); + }); + + it('should set publish_mode from config', () => { + expect(config.applyDefaults({ + foo: 'bar', + publish_mode: 'complex', + media_folder: 'path/to/media', + })).toEqual({ + foo: 'bar', + publish_mode: 'complex', + media_folder: 'path/to/media', + public_folder: '/path/to/media', + }); + }); + + it('should set public_folder based on media_folder if not set', () => { + expect(config.applyDefaults({ + foo: 'bar', + media_folder: 'path/to/media', + })).toEqual({ + foo: 'bar', + publish_mode: 'simple', + media_folder: 'path/to/media', + public_folder: '/path/to/media', + }); + }); + + it('should not overwrite public_folder if set', () => { + expect(config.applyDefaults({ + foo: 'bar', + media_folder: 'path/to/media', + public_folder: '/publib/path', + })).toEqual({ + foo: 'bar', + publish_mode: 'simple', + media_folder: 'path/to/media', + public_folder: '/publib/path', + }); + }); + }); +}); diff --git a/src/actions/config.js b/src/actions/config.js index 9500df2f..d6eee944 100644 --- a/src/actions/config.js +++ b/src/actions/config.js @@ -1,22 +1,56 @@ import yaml from 'js-yaml'; +import { set, defaultsDeep } from 'lodash'; import { currentBackend } from '../backends/backend'; import { authenticate } from '../actions/auth'; import * as MediaProxy from '../valueObjects/MediaProxy'; +import * as publishModes from '../constants/publishModes'; export const CONFIG_REQUEST = 'CONFIG_REQUEST'; export const CONFIG_SUCCESS = 'CONFIG_SUCCESS'; export const CONFIG_FAILURE = 'CONFIG_FAILURE'; +const defaults = { + publish_mode: publishModes.SIMPLE, +}; + +export function applyDefaults(config) { + if (!('media_folder' in config)) { + throw new Error('Config: `media_folder` setting could not be found in config.'); + } + + // Make sure there is a public folder + set(defaults, + 'public_folder', + config.media_folder.charAt(0) === '/' ? config.media_folder : `/${ config.media_folder }`); + + return defaultsDeep(config, defaults); +} + +function parseConfig(data) { + const config = yaml.safeLoad(data); + if (typeof CMS_ENV === 'string' && config[CMS_ENV]) { + // TODO: Add tests and refactor + for (const key in config[CMS_ENV]) { // eslint-disable-line no-restricted-syntax + if (config[CMS_ENV].hasOwnProperty(key)) { // eslint-disable-line no-prototype-builtins + config[key] = config[CMS_ENV][key]; + } + } + } + + return config; +} + + export function configLoaded(config) { return { type: CONFIG_SUCCESS, - payload: config + payload: config, }; } export function configLoading() { return { - type: CONFIG_REQUEST + type: CONFIG_REQUEST, }; } @@ -24,7 +58,7 @@ export function configFailed(err) { return { type: CONFIG_FAILURE, error: 'Error loading config', - payload: err + payload: err, }; } @@ -35,40 +69,30 @@ export function configDidLoad(config) { }; } - -export function loadConfig(config) { +export function loadConfig() { if (window.CMS_CONFIG) { return configDidLoad(window.CMS_CONFIG); } - return (dispatch, getState) => { + return (dispatch) => { dispatch(configLoading()); fetch('config.yml').then((response) => { if (response.status !== 200) { - throw `Failed to load config.yml (${response.status})`; + throw new Error(`Failed to load config.yml (${ response.status })`); } - response.text().then(parseConfig).then((config) => { - dispatch(configDidLoad(config)); - const backend = currentBackend(config); - const user = backend && backend.currentUser(); - user && dispatch(authenticate(user)); - }); + response + .text() + .then(parseConfig) + .then(applyDefaults) + .then((config) => { + dispatch(configDidLoad(config)); + const backend = currentBackend(config); + const user = backend && backend.currentUser(); + if (user) dispatch(authenticate(user)); + }); }).catch((err) => { dispatch(configFailed(err)); }); }; } - -function parseConfig(data) { - const config = yaml.safeLoad(data); - if (typeof CMS_ENV === 'string' && config[CMS_ENV]) { - for (var key in config[CMS_ENV]) { - if (config[CMS_ENV].hasOwnProperty(key)) { - config[key] = config[CMS_ENV][key]; - } - } - } - - return config; -} diff --git a/src/reducers/__tests__/collections.spec.js b/src/reducers/__tests__/collections.spec.js index 11b70adf..d57150bc 100644 --- a/src/reducers/__tests__/collections.spec.js +++ b/src/reducers/__tests__/collections.spec.js @@ -13,12 +13,23 @@ describe('collections', () => { it('should load the collections from the config', () => { expect( - collections(undefined, configLoaded({ collections: [ - { name: 'posts', folder: '_posts', fields: [{ name: 'title', widget: 'string' }] }, - ] })) + collections(undefined, configLoaded({ + collections: [ + { + name: 'posts', + folder: '_posts', + fields: [{ name: 'title', widget: 'string' }], + }, + ], + })) ).toEqual( OrderedMap({ - posts: fromJS({ name: 'posts', folder: '_posts', fields: [{ name: 'title', widget: 'string' }] }), + posts: fromJS({ + name: 'posts', + folder: '_posts', + fields: [{ name: 'title', widget: 'string' }], + type: 'folder_based_collection', + }), }) ); }); diff --git a/src/reducers/config.js b/src/reducers/config.js index 15985a75..088b014c 100644 --- a/src/reducers/config.js +++ b/src/reducers/config.js @@ -1,28 +1,12 @@ import Immutable from 'immutable'; -import _ from 'lodash'; -import * as publishModes from '../constants/publishModes'; import { CONFIG_REQUEST, CONFIG_SUCCESS, CONFIG_FAILURE } from '../actions/config'; -const defaults = { - publish_mode: publishModes.SIMPLE -}; - -const applyDefaults = (config) => { - // Make sure there is a public folder - _.set(defaults, - 'public_folder', - config.media_folder.charAt(0) === '/' ? config.media_folder : '/' + config.media_folder); - - return _.defaultsDeep(config, defaults); -}; - const config = (state = null, action) => { switch (action.type) { case CONFIG_REQUEST: return Immutable.Map({ isFetching: true }); case CONFIG_SUCCESS: - const config = applyDefaults(action.payload); - return Immutable.fromJS(config); + return Immutable.fromJS(action.payload); case CONFIG_FAILURE: return Immutable.Map({ error: action.payload.toString() }); default: