diff --git a/lib/gui/app/app.js b/lib/gui/app/app.js index 2f1bb576..1e3a8fbd 100644 --- a/lib/gui/app/app.js +++ b/lib/gui/app/app.js @@ -33,16 +33,16 @@ const EXIT_CODES = require('../../shared/exit-codes') const messages = require('../../shared/messages') const s3Packages = require('../../shared/s3-packages') const release = require('../../shared/release') -const store = require('../../shared/store') +const store = require('./models/store') const errors = require('../../shared/errors') const packageJSON = require('../../../package.json') -const flashState = require('../../shared/models/flash-state') +const flashState = require('./models/flash-state') const settings = require('./models/settings') const windowProgress = require('./os/window-progress') const analytics = require('./modules/analytics') const updateNotifier = require('./components/update-notifier') -const availableDrives = require('../../shared/models/available-drives') -const selectionState = require('../../shared/models/selection-state') +const availableDrives = require('./models/available-drives') +const selectionState = require('./models/selection-state') const driveScanner = require('./modules/drive-scanner') const osDialog = require('./os/dialog') const exceptionReporter = require('./modules/exception-reporter') @@ -190,7 +190,7 @@ app.run(() => { }) app.run(() => { - store.subscribe(() => { + store.observe(() => { if (!flashState.isFlashing()) { return } diff --git a/lib/gui/app/components/drive-selector/controllers/drive-selector.js b/lib/gui/app/components/drive-selector/controllers/drive-selector.js index 0b873049..c008cf9c 100644 --- a/lib/gui/app/components/drive-selector/controllers/drive-selector.js +++ b/lib/gui/app/components/drive-selector/controllers/drive-selector.js @@ -21,8 +21,8 @@ const _ = require('lodash') const Bluebird = require('bluebird') const constraints = require('../../../../../shared/drive-constraints') const analytics = require('../../../modules/analytics') -const availableDrives = require('../../../../../shared/models/available-drives') -const selectionState = require('../../../../../shared/models/selection-state') +const availableDrives = require('../../../models/available-drives') +const selectionState = require('../../../models/selection-state') const utils = require('../../../../../shared/utils') module.exports = function ( diff --git a/lib/gui/app/components/file-selector/file-selector/file-selector.jsx b/lib/gui/app/components/file-selector/file-selector/file-selector.jsx index 4484d01f..c1241b9e 100644 --- a/lib/gui/app/components/file-selector/file-selector/file-selector.jsx +++ b/lib/gui/app/components/file-selector/file-selector/file-selector.jsx @@ -37,7 +37,7 @@ const Storage = require('../../../models/storage') const analytics = require('../../../modules/analytics') const middleEllipsis = require('../../../utils/middle-ellipsis') const files = require('../../../../../shared/files') -const selectionState = require('../../../../../shared/models/selection-state') +const selectionState = require('../../../models/selection-state') const imageStream = require('../../../../../sdk/image-stream') const errors = require('../../../../../shared/errors') const messages = require('../../../../../shared/messages') diff --git a/lib/gui/app/components/flash-error-modal/services/flash-error-modal.js b/lib/gui/app/components/flash-error-modal/services/flash-error-modal.js index 811b203b..42494138 100644 --- a/lib/gui/app/components/flash-error-modal/services/flash-error-modal.js +++ b/lib/gui/app/components/flash-error-modal/services/flash-error-modal.js @@ -16,8 +16,8 @@ 'use strict' -const flashState = require('../../../../../shared/models/flash-state') -const selectionState = require('../../../../../shared/models/selection-state') +const flashState = require('../../../models/flash-state') +const selectionState = require('../../../models/selection-state') const analytics = require('../../../modules/analytics') module.exports = function (WarningModalService) { diff --git a/lib/shared/models/available-drives.js b/lib/gui/app/models/available-drives.js similarity index 97% rename from lib/shared/models/available-drives.js rename to lib/gui/app/models/available-drives.js index 4d73b352..78e4b525 100644 --- a/lib/shared/models/available-drives.js +++ b/lib/gui/app/models/available-drives.js @@ -17,7 +17,7 @@ 'use strict' const _ = require('lodash') -const store = require('../store') +const store = require('./store') /** * @summary Check if there are available drives diff --git a/lib/shared/models/flash-state.js b/lib/gui/app/models/flash-state.js similarity index 98% rename from lib/shared/models/flash-state.js rename to lib/gui/app/models/flash-state.js index 8ae20d10..9c28ce1e 100644 --- a/lib/shared/models/flash-state.js +++ b/lib/gui/app/models/flash-state.js @@ -17,8 +17,8 @@ 'use strict' const _ = require('lodash') -const store = require('../store') -const units = require('../units') +const store = require('./store') +const units = require('../../../shared/units') /** * @summary Reset flash state diff --git a/lib/gui/app/models/local-settings.js b/lib/gui/app/models/local-settings.js index b95e7990..3405b5fc 100644 --- a/lib/gui/app/models/local-settings.js +++ b/lib/gui/app/models/local-settings.js @@ -16,39 +16,49 @@ 'use strict' +const electron = require('electron') const Bluebird = require('bluebird') -const _ = require('lodash') const fs = require('fs') const path = require('path') -const os = require('os') -const Storage = require('./storage') /** - * @summary Local storage settings key + * @summary Number of spaces to indent JSON output with + * @type {Number} + * @constant + */ +const JSON_INDENT = 2 + +/** + * @summary Userdata directory path + * @description + * Defaults to the following: + * - `%APPDATA%/etcher` on Windows + * - `$XDG_CONFIG_HOME/etcher` or `~/.config/etcher` on Linux + * - `~/Library/Application Support/etcher` on macOS + * See https://electronjs.org/docs/api/app#appgetpathname * @constant * @type {String} */ -const LOCAL_STORAGE_SETTINGS_KEY = 'etcher-settings' -const settingsStorage = new Storage(LOCAL_STORAGE_SETTINGS_KEY) +const USER_DATA_DIR = electron.remote.app.getPath('userData') /** - * @summary Local settings filename - * @constant + * @summary Configuration file path * @type {String} + * @constant */ -const RCFILE = '.etcher.json' +const CONFIG_PATH = path.join(USER_DATA_DIR, 'config.json') /** - * @summary Read a local .etcherrc file + * @summary Read a local config.json file * @function - * @public + * @private * * @param {String} filename - file path * @fulfil {Object} - settings * @returns {Promise} * * @example - * readConfigFile('.etcherrc').then((settings) => { + * readConfigFile('config.json').then((settings) => { * console.log(settings) * }) */ @@ -68,6 +78,35 @@ const readConfigFile = (filename) => { }) } +/** + * @summary Write to the local configuration file + * @function + * @private + * + * @param {String} filename - file path + * @param {Object} data - data + * @fulfil {Object} data - data + * @returns {Promise} + * + * @example + * writeConfigFile('config.json', { something: 'good' }) + * .then(() => { + * console.log('data written') + * }) + */ +const writeConfigFile = (filename, data) => { + return new Bluebird((resolve, reject) => { + const contents = JSON.stringify(data, null, JSON_INDENT) + fs.writeFile(filename, contents, (error) => { + if (error) { + reject(error) + } else { + resolve(data) + } + }) + }) +} + /** * @summary Read all local settings * @function @@ -82,22 +121,7 @@ const readConfigFile = (filename) => { * }); */ exports.readAll = () => { - const homeConfigPath = process.platform === 'win32' - ? path.join(os.userInfo().homedir, RCFILE) - : path.join(os.userInfo().homedir, '.config', 'etcher', 'config.json') - const workdirConfigPath = path.join(process.cwd(), RCFILE) - const settings = {} - return Bluebird.try(() => { - _.merge(settings, settingsStorage.getAll()) - }).return(readConfigFile(homeConfigPath)) - .then((homeConfig) => { - _.merge(settings, homeConfig) - }) - .return(readConfigFile(workdirConfigPath)) - .then((workdirConfig) => { - _.merge(settings, workdirConfig) - }) - .return(settings) + return readConfigFile(CONFIG_PATH) } /** @@ -106,6 +130,7 @@ exports.readAll = () => { * @public * * @param {Object} settings - settings + * @fulfil {Object} settings - settings * @returns {Promise} * * @example @@ -116,9 +141,7 @@ exports.readAll = () => { * }); */ exports.writeAll = (settings) => { - return Bluebird.try(() => { - settingsStorage.setAll(settings) - }) + return writeConfigFile(CONFIG_PATH, settings) } /** @@ -137,7 +160,13 @@ exports.writeAll = (settings) => { * }); */ exports.clear = () => { - return Bluebird.try(() => { - settingsStorage.clearAll() + return new Bluebird((resolve, reject) => { + fs.unlink(CONFIG_PATH, (error) => { + if (error) { + reject(error) + } else { + resolve() + } + }) }) } diff --git a/lib/shared/models/selection-state.js b/lib/gui/app/models/selection-state.js similarity index 99% rename from lib/shared/models/selection-state.js rename to lib/gui/app/models/selection-state.js index 245d12fb..56af929d 100644 --- a/lib/shared/models/selection-state.js +++ b/lib/gui/app/models/selection-state.js @@ -17,7 +17,7 @@ 'use strict' const _ = require('lodash') -const store = require('../store') +const store = require('./store') const availableDrives = require('./available-drives') /** diff --git a/lib/gui/app/models/settings.js b/lib/gui/app/models/settings.js index 48ce87dd..3364d69c 100644 --- a/lib/gui/app/models/settings.js +++ b/lib/gui/app/models/settings.js @@ -23,58 +23,34 @@ const _ = require('lodash') const Bluebird = require('bluebird') const localSettings = require('./local-settings') -const store = require('../../../shared/store') const errors = require('../../../shared/errors') - -/** - * @summary Set a settings object - * @function - * @private - * - * @description - * Use this function with care, given that it will completely - * override any existing settings in both the redux store, - * and the local user configuration. - * - * This function is prepared to deal with any local configuration - * write issues by rolling back to the previous settings if so. - * - * @param {Object} settings - settings - * @returns {Promise} - * - * @example - * setSettingsObject({ foo: 'bar' }).then(() => { - * console.log('Done!'); - * }); - */ -const setSettingsObject = (settings) => { - const currentSettings = exports.getAll() - - return Bluebird.try(() => { - store.dispatch({ - type: store.Actions.SET_SETTINGS, - data: settings - }) - }).then(() => { - // Revert the application state if writing the data - // to the local machine was not successful - return localSettings.writeAll(settings).catch((error) => { - store.dispatch({ - type: store.Actions.SET_SETTINGS, - data: currentSettings - }) - - throw error - }) - }) -} +const release = require('../../../shared/release') +const packageJSON = require('../../../../package.json') +const debug = require('debug')('etcher:models:settings') /** * @summary Default settings * @constant * @type {Object} */ -const DEFAULT_SETTINGS = store.Defaults.get('settings').toJS() +const DEFAULT_SETTINGS = { + unsafeMode: false, + errorReporting: true, + unmountOnSuccess: true, + validateWriteOnSuccess: true, + updatesEnabled: packageJSON.updates.enabled && !_.includes([ 'rpm', 'deb' ], packageJSON.packageType), + includeUnstableUpdateChannel: !release.isStableRelease(packageJSON.version), + lastSleptUpdateNotifier: null, + lastSleptUpdateNotifierVersion: null, + desktopNotifications: true +} + +/** + * @summary Settings state + * @type {Object} + * @private + */ +let settings = _.cloneDeep(DEFAULT_SETTINGS) /** * @summary Reset settings to their default values @@ -89,7 +65,11 @@ const DEFAULT_SETTINGS = store.Defaults.get('settings').toJS() * }); */ exports.reset = () => { - return setSettingsObject(DEFAULT_SETTINGS) + debug('reset') + + // TODO: Remove default settings from config file (?) + settings = _.cloneDeep(DEFAULT_SETTINGS) + return localSettings.writeAll(settings) } /** @@ -97,7 +77,7 @@ exports.reset = () => { * @function * @public * - * @param {Object} settings - settings + * @param {Object} value - value * @returns {Promise} * * @example @@ -107,14 +87,27 @@ exports.reset = () => { * console.log('Done!'); * }); */ -exports.assign = (settings) => { - if (_.isNil(settings)) { +exports.assign = (value) => { + debug('assign', value) + if (_.isNil(value)) { return Bluebird.reject(errors.createError({ title: 'Missing settings' })) } - return setSettingsObject(_.assign(exports.getAll(), settings)) + if (!_.isPlainObject(value)) { + return Bluebird.reject(errors.createError({ + title: 'Settings must be an object' + })) + } + + const newSettings = _.assign({}, settings, value) + + return localSettings.writeAll(newSettings) + .then((updatedSettings) => { + // NOTE: Only update in memory settings when successfully written + settings = updatedSettings + }) } /** @@ -130,7 +123,10 @@ exports.assign = (settings) => { * }); */ exports.load = () => { - return localSettings.readAll().then(exports.assign) + debug('load') + return localSettings.readAll().then((loadedSettings) => { + return _.assign(settings, loadedSettings) + }) } /** @@ -148,6 +144,7 @@ exports.load = () => { * }); */ exports.set = (key, value) => { + debug('set', key, value) if (_.isNil(key)) { return Bluebird.reject(errors.createError({ title: 'Missing setting key' @@ -160,9 +157,16 @@ exports.set = (key, value) => { })) } - return exports.assign({ - [key]: value - }) + const previousValue = settings[key] + + settings[key] = value + + return localSettings.writeAll(settings) + .catch((error) => { + // Revert to previous value if persisting settings failed + settings[key] = previousValue + throw error + }) } /** @@ -177,7 +181,7 @@ exports.set = (key, value) => { * const value = settings.get('unmountOnSuccess'); */ exports.get = (key) => { - return _.get(exports.getAll(), [ key ]) + return _.cloneDeep(_.get(settings, [ key ])) } /** @@ -192,5 +196,22 @@ exports.get = (key) => { * console.log(allSettings.unmountOnSuccess); */ exports.getAll = () => { - return store.getState().get('settings').toJS() + debug('getAll') + return _.cloneDeep(settings) +} + +/** + * @summary Get the default setting values + * @function + * @public + * + * @returns {Object} all setting values + * + * @example + * const defaults = settings.getDefaults(); + * console.log(defaults.unmountOnSuccess); + */ +exports.getDefaults = () => { + debug('getDefaults') + return _.cloneDeep(DEFAULT_SETTINGS) } diff --git a/lib/shared/store.js b/lib/gui/app/models/store.js similarity index 90% rename from lib/shared/store.js rename to lib/gui/app/models/store.js index d4d1be29..262a632a 100644 --- a/lib/shared/store.js +++ b/lib/gui/app/models/store.js @@ -20,13 +20,11 @@ const Immutable = require('immutable') const _ = require('lodash') const redux = require('redux') const uuidV4 = require('uuid/v4') -const constraints = require('./drive-constraints') -const supportedFormats = require('./supported-formats') -const errors = require('./errors') -const release = require('./release') -const fileExtensions = require('./file-extensions') -const utils = require('./utils') -const packageJSON = require('../../package.json') +const constraints = require('../../../shared/drive-constraints') +const supportedFormats = require('../../../shared/supported-formats') +const errors = require('../../../shared/errors') +const fileExtensions = require('../../../shared/file-extensions') +const utils = require('../../../shared/utils') /** * @summary Verify and throw if any state fields are nil @@ -95,17 +93,6 @@ const DEFAULT_STATE = Immutable.fromJS({ percentage: 0, speed: 0, totalSpeed: 0 - }, - settings: { - unsafeMode: false, - errorReporting: true, - unmountOnSuccess: true, - validateWriteOnSuccess: true, - updatesEnabled: packageJSON.updates.enabled && !_.includes([ 'rpm', 'deb' ], packageJSON.packageType), - includeUnstableUpdateChannel: !release.isStableRelease(packageJSON.version), - lastSleptUpdateNotifier: null, - lastSleptUpdateNotifierVersion: null, - desktopNotifications: true } }) @@ -123,8 +110,7 @@ const ACTIONS = _.fromPairs(_.map([ 'SELECT_DRIVE', 'SELECT_IMAGE', 'DESELECT_DRIVE', - 'DESELECT_IMAGE', - 'SET_SETTINGS' + 'DESELECT_IMAGE' ], (message) => { return [ message, message ] })) @@ -512,34 +498,6 @@ const storeReducer = (state = DEFAULT_STATE, action) => { return state.deleteIn([ 'selection', 'image' ]) } - case ACTIONS.SET_SETTINGS: { - // Type: action.data : SettingsObject - - if (!action.data) { - throw errors.createError({ - title: 'Missing settings' - }) - } - - if (!_.isPlainObject(action.data)) { - throw errors.createError({ - title: `Invalid settings: ${action.data}` - }) - } - - const invalidPair = _.find(_.toPairs(action.data), (pair) => { - return _.isObject(_.last(pair)) - }) - - if (!_.isNil(invalidPair)) { - throw errors.createError({ - title: `Invalid setting value: ${_.last(invalidPair)} for ${_.first(invalidPair)}` - }) - } - - return state.setIn([ 'settings' ], Immutable.fromJS(action.data)) - } - default: { return state } @@ -550,3 +508,34 @@ module.exports = _.merge(redux.createStore(storeReducer, DEFAULT_STATE), { Actions: ACTIONS, Defaults: DEFAULT_STATE }) + +/** + * @summary Observe the store for changes + * @param {Function} onChange - change handler + * @returns {Function} unsubscribe + * @example + * store.observe((newState) => { + * // ... + * }) + */ +module.exports.observe = (onChange) => { + let currentState = null + + /** + * @summary Internal change detection handler + * @private + * @example + * store.subscribe(changeHandler) + */ + const changeHandler = () => { + const nextState = module.exports.getState() + if (!_.isEqual(nextState, currentState)) { + currentState = nextState + onChange(currentState) + } + } + + changeHandler() + + return module.exports.subscribe(changeHandler) +} diff --git a/lib/gui/app/modules/image-writer.js b/lib/gui/app/modules/image-writer.js index c86cff34..22dd826a 100644 --- a/lib/gui/app/modules/image-writer.js +++ b/lib/gui/app/modules/image-writer.js @@ -24,14 +24,14 @@ const ipc = require('node-ipc') const isRunningInAsar = require('electron-is-running-in-asar') const electron = require('electron') const settings = require('../models/settings') -const flashState = require('../../../shared/models/flash-state') +const flashState = require('../models/flash-state') const errors = require('../../../shared/errors') const permissions = require('../../../shared/permissions') const windowProgress = require('../os/window-progress') const analytics = require('../modules/analytics') const updateLock = require('./update-lock') const packageJSON = require('../../../../package.json') -const selectionState = require('../../../shared/models/selection-state') +const selectionState = require('../models/selection-state') /** * @summary Number of threads per CPU to allocate to the UV_THREADPOOL diff --git a/lib/gui/app/pages/finish/controllers/finish.js b/lib/gui/app/pages/finish/controllers/finish.js index 1bf94592..6bd52279 100644 --- a/lib/gui/app/pages/finish/controllers/finish.js +++ b/lib/gui/app/pages/finish/controllers/finish.js @@ -18,8 +18,8 @@ const _ = require('lodash') const settings = require('../../../models/settings') -const flashState = require('../../../../../shared/models/flash-state') -const selectionState = require('../../../../../shared/models/selection-state') +const flashState = require('../../../models/flash-state') +const selectionState = require('../../../models/selection-state') const analytics = require('../../../modules/analytics') const updateLock = require('../../../modules/update-lock') const messages = require('../../../../../shared/messages') diff --git a/lib/gui/app/pages/main/controllers/drive-selection.js b/lib/gui/app/pages/main/controllers/drive-selection.js index 318f055f..8a834616 100644 --- a/lib/gui/app/pages/main/controllers/drive-selection.js +++ b/lib/gui/app/pages/main/controllers/drive-selection.js @@ -20,7 +20,7 @@ const _ = require('lodash') const angular = require('angular') const prettyBytes = require('pretty-bytes') const settings = require('../../../models/settings') -const selectionState = require('../../../../../shared/models/selection-state') +const selectionState = require('../../../models/selection-state') const analytics = require('../../../modules/analytics') const exceptionReporter = require('../../../modules/exception-reporter') const utils = require('../../../../../shared/utils') diff --git a/lib/gui/app/pages/main/controllers/flash.js b/lib/gui/app/pages/main/controllers/flash.js index bc3f0918..4188f019 100644 --- a/lib/gui/app/pages/main/controllers/flash.js +++ b/lib/gui/app/pages/main/controllers/flash.js @@ -18,16 +18,16 @@ const _ = require('lodash') const messages = require('../../../../../shared/messages') -const flashState = require('../../../../../shared/models/flash-state') +const flashState = require('../../../models/flash-state') const driveScanner = require('../../../modules/drive-scanner') const progressStatus = require('../../../modules/progress-status') const notification = require('../../../os/notification') const exceptionReporter = require('../../../modules/exception-reporter') const imageWriter = require('../../../modules/image-writer') const path = require('path') -const store = require('../../../../../shared/store') +const store = require('../../../models/store') const constraints = require('../../../../../shared/drive-constraints') -const availableDrives = require('../../../../../shared/models/available-drives') +const availableDrives = require('../../../models/available-drives') module.exports = function ( $q, @@ -139,7 +139,7 @@ module.exports = function ( // Trigger Angular digests along with store updates, as the flash state // updates. Without this there is essentially no progress to watch. - const unsubscribe = store.subscribe($timeout) + const unsubscribe = store.observe($timeout) const iconPath = '../../../assets/icon.png' diff --git a/lib/gui/app/pages/main/controllers/image-selection.js b/lib/gui/app/pages/main/controllers/image-selection.js index 8f35cd53..6a7be5bb 100644 --- a/lib/gui/app/pages/main/controllers/image-selection.js +++ b/lib/gui/app/pages/main/controllers/image-selection.js @@ -24,7 +24,7 @@ const errors = require('../../../../../shared/errors') const imageStream = require('../../../../../sdk/image-stream') const supportedFormats = require('../../../../../shared/supported-formats') const analytics = require('../../../modules/analytics') -const selectionState = require('../../../../../shared/models/selection-state') +const selectionState = require('../../../models/selection-state') const osDialog = require('../../../os/dialog') const exceptionReporter = require('../../../modules/exception-reporter') diff --git a/lib/gui/app/pages/main/controllers/main.js b/lib/gui/app/pages/main/controllers/main.js index a99d7bbb..ba60fb46 100644 --- a/lib/gui/app/pages/main/controllers/main.js +++ b/lib/gui/app/pages/main/controllers/main.js @@ -17,11 +17,11 @@ 'use strict' const settings = require('../../../models/settings') -const flashState = require('../../../../../shared/models/flash-state') +const flashState = require('../../../models/flash-state') const analytics = require('../../../modules/analytics') const exceptionReporter = require('../../../modules/exception-reporter') -const availableDrives = require('../../../../../shared/models/available-drives') -const selectionState = require('../../../../../shared/models/selection-state') +const availableDrives = require('../../../models/available-drives') +const selectionState = require('../../../models/selection-state') const driveConstraints = require('../../../../../shared/drive-constraints') const messages = require('../../../../../shared/messages') diff --git a/tests/gui/models/settings.spec.js b/tests/gui/models/settings.spec.js index 23d91c4d..bbc672bd 100644 --- a/tests/gui/models/settings.spec.js +++ b/tests/gui/models/settings.spec.js @@ -19,7 +19,6 @@ const m = require('mochainon') const _ = require('lodash') const Bluebird = require('bluebird') -const store = require('../../../lib/shared/store') const settings = require('../../../lib/gui/app/models/settings') const localSettings = require('../../../lib/gui/app/models/local-settings') @@ -28,7 +27,7 @@ describe('Browser: settings', function () { return settings.reset() }) - const DEFAULT_SETTINGS = store.Defaults.get('settings').toJS() + const DEFAULT_SETTINGS = settings.getDefaults() it('should be able to set and read values', function () { m.chai.expect(settings.get('foo')).to.be.undefined @@ -82,17 +81,6 @@ describe('Browser: settings', function () { }) }) - it('should throw if setting an array', function (done) { - settings.assign({ - foo: 'bar', - bar: [ 1, 2, 3 ] - }).asCallback((error) => { - m.chai.expect(error).to.be.an.instanceof(Error) - m.chai.expect(error.message).to.equal('Invalid setting value: 1,2,3 for bar') - done() - }) - }) - it('should not override all settings', function () { return settings.assign({ foo: 'bar', @@ -105,24 +93,6 @@ describe('Browser: settings', function () { }) }) - it('should not store invalid settings to the local machine', function () { - return localSettings.readAll().then((data) => { - m.chai.expect(data.foo).to.be.undefined - - return new Bluebird((resolve) => { - settings.assign({ - foo: [ 1, 2, 3 ] - }).asCallback((error) => { - m.chai.expect(error).to.be.an.instanceof(Error) - m.chai.expect(error.message).to.equal('Invalid setting value: 1,2,3 for foo') - return resolve() - }) - }) - }).then(localSettings.readAll).then((data) => { - m.chai.expect(data.foo).to.be.undefined - }) - }) - it('should store the settings to the local machine', function () { return localSettings.readAll().then((data) => { m.chai.expect(data.foo).to.be.undefined @@ -206,20 +176,10 @@ describe('Browser: settings', function () { }) }) - it('should throw if setting an object', function (done) { - settings.set('foo', { - setting: 1 - }).asCallback((error) => { - m.chai.expect(error).to.be.an.instanceof(Error) - m.chai.expect(error.message).to.equal('Invalid setting value: [object Object] for foo') - done() - }) - }) - it('should throw if setting an array', function (done) { - settings.set('foo', [ 1, 2, 3 ]).asCallback((error) => { + settings.assign([ 1, 2, 3 ]).asCallback((error) => { m.chai.expect(error).to.be.an.instanceof(Error) - m.chai.expect(error.message).to.equal('Invalid setting value: 1,2,3 for foo') + m.chai.expect(error.message).to.equal('Settings must be an object') done() }) }) @@ -242,22 +202,6 @@ describe('Browser: settings', function () { }) }) - it('should not store invalid settings to the local machine', function () { - return localSettings.readAll().then((data) => { - m.chai.expect(data.foo).to.be.undefined - - return new Bluebird((resolve) => { - settings.set('foo', [ 1, 2, 3 ]).asCallback((error) => { - m.chai.expect(error).to.be.an.instanceof(Error) - m.chai.expect(error.message).to.equal('Invalid setting value: 1,2,3 for foo') - return resolve() - }) - }) - }).then(localSettings.readAll).then((data) => { - m.chai.expect(data.foo).to.be.undefined - }) - }) - it('should not change the application state if storing to the local machine results in an error', function (done) { settings.set('foo', 'bar').then(() => { m.chai.expect(settings.get('foo')).to.equal('bar') diff --git a/tests/gui/modules/image-writer.spec.js b/tests/gui/modules/image-writer.spec.js index b566babf..8aadf5df 100644 --- a/tests/gui/modules/image-writer.spec.js +++ b/tests/gui/modules/image-writer.spec.js @@ -4,7 +4,7 @@ const m = require('mochainon') const ipc = require('node-ipc') const angular = require('angular') const Bluebird = require('bluebird') -const flashState = require('../../../lib/shared/models/flash-state') +const flashState = require('../../../lib/gui/app/models/flash-state') const imageWriter = require('../../../lib/gui/app/modules/image-writer') require('angular-mocks') diff --git a/tests/gui/pages/main.spec.js b/tests/gui/pages/main.spec.js index e20c0c44..05e78305 100644 --- a/tests/gui/pages/main.spec.js +++ b/tests/gui/pages/main.spec.js @@ -22,9 +22,9 @@ const fs = require('fs') const path = require('path') const supportedFormats = require('../../../lib/shared/supported-formats') const angular = require('angular') -const flashState = require('../../../lib/shared/models/flash-state') -const availableDrives = require('../../../lib/shared/models/available-drives') -const selectionState = require('../../../lib/shared/models/selection-state') +const flashState = require('../../../lib/gui/app/models/flash-state') +const availableDrives = require('../../../lib/gui/app/models/available-drives') +const selectionState = require('../../../lib/gui/app/models/selection-state') require('angular-mocks') // Mock HTML requires by reading from the file-system diff --git a/tests/shared/models/available-drives.spec.js b/tests/shared/models/available-drives.spec.js index 7c33bc85..28a8a194 100644 --- a/tests/shared/models/available-drives.spec.js +++ b/tests/shared/models/available-drives.spec.js @@ -18,8 +18,8 @@ const m = require('mochainon') const path = require('path') -const availableDrives = require('../../../lib/shared/models/available-drives') -const selectionState = require('../../../lib/shared/models/selection-state') +const availableDrives = require('../../../lib/gui/app/models/available-drives') +const selectionState = require('../../../lib/gui/app/models/selection-state') const constraints = require('../../../lib/shared/drive-constraints') describe('Model: availableDrives', function () { diff --git a/tests/shared/models/flash-state.spec.js b/tests/shared/models/flash-state.spec.js index 5faeb59d..6973cdb4 100644 --- a/tests/shared/models/flash-state.spec.js +++ b/tests/shared/models/flash-state.spec.js @@ -17,7 +17,7 @@ 'use strict' const m = require('mochainon') -const flashState = require('../../../lib/shared/models/flash-state') +const flashState = require('../../../lib/gui/app/models/flash-state') describe('Model: flashState', function () { beforeEach(function () { diff --git a/tests/shared/models/selection-state.spec.js b/tests/shared/models/selection-state.spec.js index d3bec552..cf276589 100644 --- a/tests/shared/models/selection-state.spec.js +++ b/tests/shared/models/selection-state.spec.js @@ -19,8 +19,8 @@ const m = require('mochainon') const _ = require('lodash') const path = require('path') -const availableDrives = require('../../../lib/shared/models/available-drives') -const selectionState = require('../../../lib/shared/models/selection-state') +const availableDrives = require('../../../lib/gui/app/models/available-drives') +const selectionState = require('../../../lib/gui/app/models/selection-state') describe('Model: selectionState', function () { describe('given a clean state', function () {