aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkumavis <aaron@kumavis.me>2017-01-12 14:47:56 +0800
committerkumavis <aaron@kumavis.me>2017-01-12 14:47:56 +0800
commit3bc996878b467e1fa5fd63656bd465377daa137d (patch)
tree9c1661af778b58cd6d83c7d5fb5727f7a61b6dd9
parent2019c02fc0fc33d4bd98416654370250d7aa0ca6 (diff)
downloadtangerine-wallet-browser-3bc996878b467e1fa5fd63656bd465377daa137d.tar
tangerine-wallet-browser-3bc996878b467e1fa5fd63656bd465377daa137d.tar.gz
tangerine-wallet-browser-3bc996878b467e1fa5fd63656bd465377daa137d.tar.bz2
tangerine-wallet-browser-3bc996878b467e1fa5fd63656bd465377daa137d.tar.lz
tangerine-wallet-browser-3bc996878b467e1fa5fd63656bd465377daa137d.tar.xz
tangerine-wallet-browser-3bc996878b467e1fa5fd63656bd465377daa137d.tar.zst
tangerine-wallet-browser-3bc996878b467e1fa5fd63656bd465377daa137d.zip
background - move pojo migrator to outside of metamask controller
-rw-r--r--app/scripts/background.js94
-rw-r--r--app/scripts/first-time-state.js11
-rw-r--r--app/scripts/lib/config-manager.js49
-rw-r--r--app/scripts/lib/migrations.js13
-rw-r--r--app/scripts/lib/observable/host.js4
-rw-r--r--app/scripts/lib/observable/index.js10
-rw-r--r--app/scripts/lib/observable/local-storage.js37
-rw-r--r--app/scripts/lib/observable/remote.js2
-rw-r--r--app/scripts/lib/observable/util/sync.js24
-rw-r--r--app/scripts/lib/observable/util/transform.js13
-rw-r--r--app/scripts/metamask-controller.js6
-rw-r--r--mock-dev.js94
-rw-r--r--test/integration/lib/idStore-migrator-test.js44
-rw-r--r--test/lib/mock-config-manager.js64
-rw-r--r--test/unit/config-manager-test.js10
15 files changed, 231 insertions, 244 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js
index f3c0b52b3..8aa886594 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -1,41 +1,57 @@
const urlUtil = require('url')
-const extend = require('xtend')
const Dnode = require('dnode')
const eos = require('end-of-stream')
+const Migrator = require('pojo-migrator')
+const migrations = require('./lib/migrations')
+const LocalStorageStore = require('./lib/observable/local-storage')
const PortStream = require('./lib/port-stream.js')
const notification = require('./lib/notifications.js')
const messageManager = require('./lib/message-manager')
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
const MetamaskController = require('./metamask-controller')
const extension = require('./lib/extension')
+const firstTimeState = require('./first-time-state')
const STORAGE_KEY = 'metamask-config'
const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
-var popupIsOpen = false
+let popupIsOpen = false
+//
+// State and Persistence
+//
+
+// state persistence
+
+let dataStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
+// initial state for first time users
+if (!dataStore.get()) {
+ dataStore.put({ meta: { version: 0 }, data: firstTimeState })
+}
+
+// migrations
+
+let migrator = new Migrator({
+ migrations,
+ // Data persistence methods
+ loadData: () => dataStore.get(),
+ setData: (newState) => dataStore.put(newState),
+})
+
+//
+// MetaMask Controller
+//
+
const controller = new MetamaskController({
// User confirmation callbacks:
showUnconfirmedMessage: triggerUi,
unlockAccountMessage: triggerUi,
showUnapprovedTx: triggerUi,
// initial state
- initState: loadData(),
+ initState: migrator.getData(),
})
// setup state persistence
-controller.store.subscribe(setData)
-
-const txManager = controller.txManager
-function triggerUi () {
- if (!popupIsOpen) notification.show()
-}
-// On first install, open a window to MetaMask website to how-it-works.
-
-extension.runtime.onInstalled.addListener(function (details) {
- if ((details.reason === 'install') && (!METAMASK_DEBUG)) {
- extension.tabs.create({url: 'https://metamask.io/#how-it-works'})
- }
-})
+controller.store.subscribe((newState) => migrator.saveData(newState))
//
// connect to other contexts
@@ -94,11 +110,23 @@ function setupControllerConnection (stream) {
}
//
-// plugin badge text
+// User Interface setup
//
-txManager.on('updateBadge', updateBadge)
+// popup trigger
+function triggerUi () {
+ if (!popupIsOpen) notification.show()
+}
+// On first install, open a window to MetaMask website to how-it-works.
+extension.runtime.onInstalled.addListener(function (details) {
+ if ((details.reason === 'install') && (!METAMASK_DEBUG)) {
+ extension.tabs.create({url: 'https://metamask.io/#how-it-works'})
+ }
+})
+
+// plugin badge text
+controller.txManager.on('updateBadge', updateBadge)
function updateBadge () {
var label = ''
var unapprovedTxCount = controller.txManager.unapprovedTxCount
@@ -111,33 +139,3 @@ function updateBadge () {
extension.browserAction.setBadgeText({ text: label })
extension.browserAction.setBadgeBackgroundColor({ color: '#506F8B' })
}
-
-// data :: setters/getters
-
-function loadData () {
- let defaultData = {
- meta: {
- version: 0,
- },
- data: {
- config: {
- provider: {
- type: 'testnet',
- },
- },
- },
- }
-
- var persisted
- try {
- persisted = JSON.parse(window.localStorage[STORAGE_KEY])
- } catch (err) {
- persisted = null
- }
-
- return extend(defaultData, persisted)
-}
-
-function setData (data) {
- window.localStorage[STORAGE_KEY] = JSON.stringify(data)
-}
diff --git a/app/scripts/first-time-state.js b/app/scripts/first-time-state.js
new file mode 100644
index 000000000..3196981ba
--- /dev/null
+++ b/app/scripts/first-time-state.js
@@ -0,0 +1,11 @@
+//
+// The default state of MetaMask
+//
+
+module.exports = {
+ config: {
+ provider: {
+ type: 'testnet',
+ },
+ },
+} \ No newline at end of file
diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js
index 01e6ccc3c..6d7305377 100644
--- a/app/scripts/lib/config-manager.js
+++ b/app/scripts/lib/config-manager.js
@@ -1,6 +1,4 @@
-const Migrator = require('pojo-migrator')
const MetamaskConfig = require('../config.js')
-const migrations = require('./migrations')
const ethUtil = require('ethereumjs-util')
const normalize = require('./sig-util').normalize
@@ -20,38 +18,17 @@ function ConfigManager (opts) {
// ConfigManager is observable and will emit updates
this._subs = []
this.store = opts.store
-
- /* The migrator exported on the config-manager
- * has two methods the user should be concerned with:
- *
- * getData(), which returns the app-consumable data object
- * saveData(), which persists the app-consumable data object.
- */
- this.migrator = new Migrator({
-
- // Migrations must start at version 1 or later.
- // They are objects with a `version` number
- // and a `migrate` function.
- //
- // The `migrate` function receives the previous
- // config data format, and returns the new one.
- migrations: migrations,
-
- // Data persistence methods
- loadData: () => this.store.get(),
- setData: (value) => this.store.put(value),
- })
}
ConfigManager.prototype.setConfig = function (config) {
- var data = this.migrator.getData()
+ var data = this.store.get()
data.config = config
this.setData(data)
this._emitUpdates(config)
}
ConfigManager.prototype.getConfig = function () {
- var data = this.migrator.getData()
+ var data = this.store.get()
if ('config' in data) {
return data.config
} else {
@@ -94,15 +71,15 @@ ConfigManager.prototype.getProvider = function () {
}
ConfigManager.prototype.setData = function (data) {
- this.migrator.saveData(data)
+ this.store.put(data)
}
ConfigManager.prototype.getData = function () {
- return this.migrator.getData()
+ return this.store.get()
}
ConfigManager.prototype.setWallet = function (wallet) {
- var data = this.migrator.getData()
+ var data = this.store.get()
data.wallet = wallet
this.setData(data)
}
@@ -119,11 +96,11 @@ ConfigManager.prototype.getVault = function () {
}
ConfigManager.prototype.getKeychains = function () {
- return this.migrator.getData().keychains || []
+ return this.store.get().keychains || []
}
ConfigManager.prototype.setKeychains = function (keychains) {
- var data = this.migrator.getData()
+ var data = this.store.get()
data.keychains = keychains
this.setData(data)
}
@@ -140,19 +117,19 @@ ConfigManager.prototype.setSelectedAccount = function (address) {
}
ConfigManager.prototype.getWallet = function () {
- return this.migrator.getData().wallet
+ return this.store.get().wallet
}
// Takes a boolean
ConfigManager.prototype.setShowSeedWords = function (should) {
- var data = this.migrator.getData()
+ var data = this.store.get()
data.showSeedWords = should
this.setData(data)
}
ConfigManager.prototype.getShouldShowSeedWords = function () {
- var data = this.migrator.getData()
+ var data = this.store.get()
return data.showSeedWords
}
@@ -187,7 +164,7 @@ ConfigManager.prototype.getCurrentRpcAddress = function () {
}
ConfigManager.prototype.setData = function (data) {
- this.migrator.saveData(data)
+ this.store.put(data)
}
//
@@ -195,7 +172,7 @@ ConfigManager.prototype.setData = function (data) {
//
ConfigManager.prototype.getTxList = function () {
- var data = this.migrator.getData()
+ var data = this.store.get()
if (data.transactions !== undefined) {
return data.transactions
} else {
@@ -204,7 +181,7 @@ ConfigManager.prototype.getTxList = function () {
}
ConfigManager.prototype.setTxList = function (txList) {
- var data = this.migrator.getData()
+ var data = this.store.get()
data.transactions = txList
this.setData(data)
}
diff --git a/app/scripts/lib/migrations.js b/app/scripts/lib/migrations.js
index f026cbe53..12f60def1 100644
--- a/app/scripts/lib/migrations.js
+++ b/app/scripts/lib/migrations.js
@@ -1,3 +1,16 @@
+/* The migrator has two methods the user should be concerned with:
+ *
+ * getData(), which returns the app-consumable data object
+ * saveData(), which persists the app-consumable data object.
+ */
+
+// Migrations must start at version 1 or later.
+// They are objects with a `version` number
+// and a `migrate` function.
+//
+// The `migrate` function receives the previous
+// config data format, and returns the new one.
+
module.exports = [
require('../migrations/002'),
require('../migrations/003'),
diff --git a/app/scripts/lib/observable/host.js b/app/scripts/lib/observable/host.js
index 69f674be8..d1b110503 100644
--- a/app/scripts/lib/observable/host.js
+++ b/app/scripts/lib/observable/host.js
@@ -12,14 +12,14 @@ class HostStore extends ObservableStore {
constructor (initState, opts) {
super(initState)
- this.opts = opts || {}
+ this._opts = opts || {}
}
createStream () {
const self = this
// setup remotely exposed api
let remoteApi = {}
- if (!self.opts.readOnly) {
+ if (!self._opts.readOnly) {
remoteApi.put = (newState) => self.put(newState)
}
// listen for connection to remote
diff --git a/app/scripts/lib/observable/index.js b/app/scripts/lib/observable/index.js
index d193e5554..1ff112e95 100644
--- a/app/scripts/lib/observable/index.js
+++ b/app/scripts/lib/observable/index.js
@@ -7,22 +7,30 @@ class ObservableStore extends EventEmitter {
this._state = initialState
}
+ // wrapper around internal get
get () {
return this._state
}
-
+
+ // wrapper around internal put
put (newState) {
this._put(newState)
}
+ // subscribe to changes
subscribe (handler) {
this.on('update', handler)
}
+ // unsubscribe to changes
unsubscribe (handler) {
this.removeListener('update', handler)
}
+ //
+ // private
+ //
+
_put (newState) {
this._state = newState
this.emit('update', newState)
diff --git a/app/scripts/lib/observable/local-storage.js b/app/scripts/lib/observable/local-storage.js
new file mode 100644
index 000000000..6ed3860f6
--- /dev/null
+++ b/app/scripts/lib/observable/local-storage.js
@@ -0,0 +1,37 @@
+const ObservableStore = require('./index')
+
+//
+// LocalStorageStore
+//
+// uses localStorage instead of a cache
+//
+
+class LocalStorageStore extends ObservableStore {
+
+ constructor (opts) {
+ super()
+ delete this._state
+
+ this._opts = opts || {}
+ if (!this._opts.storageKey) {
+ throw new Error('LocalStorageStore - no "storageKey" specified')
+ }
+ this._storageKey = this._opts.storageKey
+ }
+
+ get() {
+ try {
+ return JSON.parse(global.localStorage[this._storageKey])
+ } catch (err) {
+ return undefined
+ }
+ }
+
+ _put(newState) {
+ global.localStorage[this._storageKey] = JSON.stringify(newState)
+ this.emit('update', newState)
+ }
+
+}
+
+module.exports = LocalStorageStore
diff --git a/app/scripts/lib/observable/remote.js b/app/scripts/lib/observable/remote.js
index b5a3254a2..603f6f0b8 100644
--- a/app/scripts/lib/observable/remote.js
+++ b/app/scripts/lib/observable/remote.js
@@ -12,7 +12,7 @@ class RemoteStore extends ObservableStore {
constructor (initState, opts) {
super(initState)
- this.opts = opts || {}
+ this._opts = opts || {}
this._remote = null
}
diff --git a/app/scripts/lib/observable/util/sync.js b/app/scripts/lib/observable/util/sync.js
new file mode 100644
index 000000000..c61feb02e
--- /dev/null
+++ b/app/scripts/lib/observable/util/sync.js
@@ -0,0 +1,24 @@
+
+//
+// synchronizeStore(inStore, outStore, stateTransform)
+//
+// keeps outStore synchronized with inStore, via an optional stateTransform
+//
+
+module.exports = synchronizeStore
+
+
+function synchronizeStore(inStore, outStore, stateTransform) {
+ stateTransform = stateTransform || transformNoop
+ const initState = stateTransform(inStore.get())
+ outStore.put(initState)
+ inStore.subscribe((inState) => {
+ const outState = stateTransform(inState)
+ outStore.put(outState)
+ })
+ return outStore
+}
+
+function transformNoop(state) {
+ return state
+} \ No newline at end of file
diff --git a/app/scripts/lib/observable/util/transform.js b/app/scripts/lib/observable/util/transform.js
deleted file mode 100644
index 87946f402..000000000
--- a/app/scripts/lib/observable/util/transform.js
+++ /dev/null
@@ -1,13 +0,0 @@
-
-module.exports = transformStore
-
-
-function transformStore(inStore, outStore, stateTransform) {
- const initState = stateTransform(inStore.get())
- outStore.put(initState)
- inStore.subscribe((inState) => {
- const outState = stateTransform(inState)
- outStore.put(outState)
- })
- return outStore
-} \ No newline at end of file
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 8e0eaf54c..e15844a56 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -14,7 +14,7 @@ const nodeify = require('./lib/nodeify')
const IdStoreMigrator = require('./lib/idStore-migrator')
const ObservableStore = require('./lib/observable/')
const HostStore = require('./lib/observable/host')
-const transformStore = require('./lib/observable/util/transform')
+const synchronizeStore = require('./lib/observable/util/sync')
const version = require('../manifest.json').version
module.exports = class MetamaskController extends EventEmitter {
@@ -244,12 +244,12 @@ module.exports = class MetamaskController extends EventEmitter {
var publicConfigStore = new HostStore(initPublicState, { readOnly: true })
// sync publicConfigStore with transform
- transformStore(this.store, publicConfigStore, selectPublicState)
+ synchronizeStore(this.store, publicConfigStore, selectPublicState)
function selectPublicState(state) {
let result = { selectedAccount: undefined }
try {
- result.selectedAccount = state.data.config.selectedAccount
+ result.selectedAccount = state.config.selectedAccount
} catch (err) {
console.warn('Error in "selectPublicState": ' + err.message)
}
diff --git a/mock-dev.js b/mock-dev.js
index dfd0b4961..a404c64b0 100644
--- a/mock-dev.js
+++ b/mock-dev.js
@@ -12,6 +12,9 @@
* To use, run `npm run mock`.
*/
+// pollyfill localStorage for non-browser environments
+if (!global.localStorage) global.localStorage
+
const extend = require('xtend')
const render = require('react-dom').render
const h = require('react-hyperscript')
@@ -21,93 +24,62 @@ const actions = require('./ui/app/actions')
const states = require('./development/states')
const Selector = require('./development/selector')
const MetamaskController = require('./app/scripts/metamask-controller')
+const firstTimeState = require('./app/scripts/first-time-state')
+const LocalStorageStore = require('./app/scripts/lib/observable/local-storage')
+const synchronizeStore = require('./app/scripts/lib/observable/util/sync')
const extension = require('./development/mockExtension')
+const noop = function () {}
+
+const STORAGE_KEY = 'metamask-config'
+//
// Query String
+//
+
const qs = require('qs')
let queryString = qs.parse(window.location.href.split('#')[1])
let selectedView = queryString.view || 'first time'
const firstState = states[selectedView]
updateQueryParams(selectedView)
+function updateQueryParams(newView) {
+ queryString.view = newView
+ const params = qs.stringify(queryString)
+ window.location.href = window.location.href.split('#')[0] + `#${params}`
+}
+
+//
// CSS
+//
+
const MetaMaskUiCss = require('./ui/css')
const injectCss = require('inject-css')
+//
+// MetaMask Controller
+//
-function updateQueryParams(newView) {
- queryString.view = newView
- const params = qs.stringify(queryString)
- window.location.href = window.location.href.split('#')[0] + `#${params}`
+let dataStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
+// initial state for first time users
+if (!dataStore.get()) {
+ dataStore.put(firstTimeState)
}
-const noop = function () {}
const controller = new MetamaskController({
// User confirmation callbacks:
showUnconfirmedMessage: noop,
unlockAccountMessage: noop,
showUnapprovedTx: noop,
// initial state
- initState: loadData(),
+ initState: dataStore.get(),
})
// setup state persistence
-controller.store.subscribe(setData)
-
-// Stub out localStorage for non-browser environments
-if (!window.localStorage) {
- window.localStorage = {}
-}
-const STORAGE_KEY = 'metamask-config'
-function loadData () {
- var oldData = getOldStyleData()
- var newData
- try {
- newData = JSON.parse(window.localStorage[STORAGE_KEY])
- } catch (e) {}
-
- var data = extend({
- meta: {
- version: 0,
- },
- data: {
- config: {
- provider: {
- type: 'testnet',
- },
- },
- },
- }, oldData || null, newData || null)
- return data
-}
-
-function setData (data) {
- window.localStorage[STORAGE_KEY] = JSON.stringify(data)
-}
-
-function getOldStyleData () {
- var config, wallet, seedWords
+synchronizeStore(controller.store, dataStore)
- var result = {
- meta: { version: 0 },
- data: {},
- }
-
- try {
- config = JSON.parse(window.localStorage['config'])
- result.data.config = config
- } catch (e) {}
- try {
- wallet = JSON.parse(window.localStorage['lightwallet'])
- result.data.wallet = wallet
- } catch (e) {}
- try {
- seedWords = window.localStorage['seedWords']
- result.data.seedWords = seedWords
- } catch (e) {}
-
- return result
-}
+//
+// User Interface
+//
actions._setBackgroundConnection(controller.getApi())
actions.update = function(stateName) {
diff --git a/test/integration/lib/idStore-migrator-test.js b/test/integration/lib/idStore-migrator-test.js
index 1ceaac442..d95cfb401 100644
--- a/test/integration/lib/idStore-migrator-test.js
+++ b/test/integration/lib/idStore-migrator-test.js
@@ -4,8 +4,8 @@ const IdStoreMigrator = require('../../../app/scripts/lib/idStore-migrator')
const SimpleKeyring = require('../../../app/scripts/keyrings/simple')
const normalize = require('../../../app/scripts/lib/sig-util').normalize
-const oldStyleVault = require('../mocks/oldVault.json')
-const badStyleVault = require('../mocks/badVault.json')
+const oldStyleVault = require('../mocks/oldVault.json').data
+const badStyleVault = require('../mocks/badVault.json').data
const PASSWORD = '12345678'
const FIRST_ADDRESS = '0x4dd5d356c5A016A220bCD69e82e5AF680a430d00'.toLowerCase()
@@ -14,15 +14,10 @@ const SEED = 'fringe damage bounce extend tunnel afraid alert sound all soldier
QUnit.module('Old Style Vaults', {
beforeEach: function () {
- let store = new ObservableStore(oldStyleVault)
-
- this.configManager = new ConfigManager({
- store: store,
- })
-
- this.migrator = new IdStoreMigrator({
- configManager: this.configManager,
- })
+ let managers = managersFromInitState(oldStyleVault)
+
+ this.configManager = managers.configManager
+ this.migrator = managers.migrator
}
})
@@ -35,6 +30,7 @@ QUnit.test('migrator:migratedVaultForPassword', function (assert) {
this.migrator.migratedVaultForPassword(PASSWORD)
.then((result) => {
+ assert.ok(result, 'migratedVaultForPassword returned result')
const { serialized, lostAccounts } = result
assert.equal(serialized.data.mnemonic, SEED, 'seed phrase recovered')
assert.equal(lostAccounts.length, 0, 'no lost accounts')
@@ -44,15 +40,10 @@ QUnit.test('migrator:migratedVaultForPassword', function (assert) {
QUnit.module('Old Style Vaults with bad HD seed', {
beforeEach: function () {
- let store = new ObservableStore(badStyleVault)
-
- this.configManager = new ConfigManager({
- store: store,
- })
-
- this.migrator = new IdStoreMigrator({
- configManager: this.configManager,
- })
+ let managers = managersFromInitState(badStyleVault)
+
+ this.configManager = managers.configManager
+ this.migrator = managers.migrator
}
})
@@ -61,6 +52,7 @@ QUnit.test('migrator:migratedVaultForPassword', function (assert) {
this.migrator.migratedVaultForPassword(PASSWORD)
.then((result) => {
+ assert.ok(result, 'migratedVaultForPassword returned result')
const { serialized, lostAccounts } = result
assert.equal(lostAccounts.length, 1, 'one lost account')
@@ -86,3 +78,15 @@ QUnit.test('migrator:migratedVaultForPassword', function (assert) {
})
})
+function managersFromInitState(initState){
+
+ let configManager = new ConfigManager({
+ store: new ObservableStore(initState),
+ })
+
+ let migrator = new IdStoreMigrator({
+ configManager: configManager,
+ })
+
+ return { configManager, migrator }
+} \ No newline at end of file
diff --git a/test/lib/mock-config-manager.js b/test/lib/mock-config-manager.js
index 0e84aa001..c62d91da9 100644
--- a/test/lib/mock-config-manager.js
+++ b/test/lib/mock-config-manager.js
@@ -1,61 +1,11 @@
const ConfigManager = require('../../app/scripts/lib/config-manager')
-const ObservableStore = require('../../app/scripts/lib/observable/')
+const LocalStorageStore = require('../../app/scripts/lib/observable/local-storage')
+const firstTimeState = require('../../app/scripts/first-time-state')
const STORAGE_KEY = 'metamask-config'
-const extend = require('xtend')
module.exports = function() {
- let store = new ObservableStore(loadData())
- store.subscribe(setData)
- return new ConfigManager({ store })
-}
-
-function loadData () {
- var oldData = getOldStyleData()
- var newData
-
- try {
- newData = JSON.parse(window.localStorage[STORAGE_KEY])
- } catch (e) {}
-
- var data = extend({
- meta: {
- version: 0,
- },
- data: {
- config: {
- provider: {
- type: 'testnet',
- },
- },
- },
- }, oldData || null, newData || null)
- return data
-}
-
-function getOldStyleData () {
- var config, wallet, seedWords
-
- var result = {
- meta: { version: 0 },
- data: {},
- }
-
- try {
- config = JSON.parse(window.localStorage['config'])
- result.data.config = config
- } catch (e) {}
- try {
- wallet = JSON.parse(window.localStorage['lightwallet'])
- result.data.wallet = wallet
- } catch (e) {}
- try {
- seedWords = window.localStorage['seedWords']
- result.data.seedWords = seedWords
- } catch (e) {}
-
- return result
-}
-
-function setData (data) {
- window.localStorage[STORAGE_KEY] = JSON.stringify(data)
-}
+ let dataStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
+ // initial state for first time users
+ if (!dataStore.get()) dataStore.put(firstTimeState)
+ return new ConfigManager({ store: dataStore })
+} \ No newline at end of file
diff --git a/test/unit/config-manager-test.js b/test/unit/config-manager-test.js
index 77d431d5f..83b242a8b 100644
--- a/test/unit/config-manager-test.js
+++ b/test/unit/config-manager-test.js
@@ -1,5 +1,8 @@
// polyfill fetch
global.fetch = global.fetch || require('isomorphic-fetch')
+// pollyfill localStorage support into JSDom
+global.localStorage = global.localStorage || polyfillLocalStorage()
+
const assert = require('assert')
const extend = require('xtend')
const rp = require('request-promise')
@@ -11,7 +14,7 @@ describe('config-manager', function() {
var configManager
beforeEach(function() {
- window.localStorage = {} // Hacking localStorage support into JSDom
+ global.localStorage.clear()
configManager = configManagerGen()
})
@@ -132,7 +135,6 @@ describe('config-manager', function() {
})
describe('#setConfig', function() {
- window.localStorage = {} // Hacking localStorage support into JSDom
it('should set the config key', function () {
var testConfig = {
@@ -238,3 +240,7 @@ describe('config-manager', function() {
})
})
})
+
+function polyfillLocalStorage(){
+ return Object.create({ clear: function(){ global.localStorage = polyfillLocalStorage() } })
+}