Skip to content

Commit

Permalink
add functions to save data to localStorage
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewglover committed Oct 6, 2016
1 parent c69805f commit 90fac36
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 41 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/*
public/*
coverage/*
9 changes: 8 additions & 1 deletion app/action_creators/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
// @flow
/* eslint-disable import/prefer-default-export */
import { UPDATE_AUTH_STATUS } from '../action_types';

export const updateAuthStatus = (isAuthenticated) =>
type updateAuthAction = {
type: string,
isAuthenticated: boolean
}


export const updateAuthStatus = (isAuthenticated: boolean): updateAuthAction =>
({
type: UPDATE_AUTH_STATUS,
isAuthenticated,
Expand Down
3 changes: 2 additions & 1 deletion app/components/app.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @flow
import React, { PropTypes } from 'react';
import { Provider } from 'react-redux';
import { Router, Route, IndexRedirect, hashHistory } from 'react-router';
Expand All @@ -14,7 +15,7 @@ const redirectIfAuthenticated = (Component, redirectPath) =>
requiresAuthentication(Component, redirectPath, false);


const App = ({ store }) =>
const App = ({ store }: { store: Object }): Object =>
<Provider store={store}>
<Router history={hashHistory}>
<Route path="/" component={Main}>
Expand Down
23 changes: 23 additions & 0 deletions app/local_storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// @flow
import { tryCatch, always } from 'ramda';
import { logError } from './loggers';

type SavedState = Object;

const dangerouslyLoadState = (): ?SavedState => {
const serializedState = window.localStorage.getItem('state');

return serializedState
? JSON.parse(serializedState)
: undefined;
};

const dangerouslySaveState = (state) => {
localStorage.setItem('state', JSON.stringify(state));
};

export const loadState =
tryCatch(dangerouslyLoadState, always(undefined));

export const saveState =
tryCatch(dangerouslySaveState, logError);
6 changes: 6 additions & 0 deletions app/loggers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-disable import/prefer-default-export, no-console */

export const logError = err => {
if (process.env.NODE_ENV !== 'development') return;
console.log(err);
};
36 changes: 0 additions & 36 deletions app/reducers/todos.js

This file was deleted.

14 changes: 13 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"flow": "flow; test $? -eq 0 -o $? -eq 2",
"lint": "eslint './**/*.js'",
"precommit": "npm run lint && npm run flow && nyc npm test && npm run coverage",
"test": "ava --verbose --require babel-register"
"test": "ava --verbose --require babel-register --require ./test/helpers/setup_browser_env.js",
"test-coverage-report": "nyc npm run test report --reporter=lcov"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -40,14 +41,18 @@
"flow-bin": "^0.32.0",
"html-webpack-plugin": "^2.22.0",
"husky": "^0.11.6",
"jsdom": "^9.6.0",
"json-loader": "^0.5.4",
"node-localstorage": "^1.3.0",
"nyc": "^8.1.0",
"sinon": "^1.17.6",
"style-loader": "^0.13.1",
"webpack": "^1.13.2",
"webpack-dev-server": "^1.15.0"
},
"dependencies": {
"@matthewglover/hapi-wrapper": "^0.2.4",
"lodash": "^4.16.3",
"material-ui": "^0.15.4",
"ramda": "^0.22.1",
"react": "^15.3.1",
Expand All @@ -62,5 +67,12 @@
},
"engines": {
"node": "6.2.2"
},
"nyc": {
"exclude": [
"node_modules",
"test",
"app/loggers.js"
]
}
}
3 changes: 2 additions & 1 deletion test/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"extends": "airbnb",
"parser": "babel-eslint",
"env": {
"node": true
"node": true,
"browser": true
},
"rules": {
"import/no-extraneous-dependencies": ["error", {"devDependencies": true}],
Expand Down
9 changes: 9 additions & 0 deletions test/helpers/setup_browser_env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { LocalStorage } from 'node-localstorage';
import { jsdom } from 'jsdom';


global.localStorage = new LocalStorage('');
global.document = jsdom('<body></body>');

global.window = document.defaultView;
global.window.localStorage = global.localStorage;
46 changes: 46 additions & 0 deletions test/local_storage.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import test, { afterEach } from 'ava';
import sinon from 'sinon';
import { loadState, saveState } from '../app/local_storage';

const testData = { test: 'It works!' };
const testPayload = JSON.stringify(testData);
const setItemStub = sinon.stub();
const getItemStub = sinon.stub();


localStorage.getItem = getItemStub;
localStorage.setItem = setItemStub;


afterEach(() => {
setItemStub.reset();
getItemStub.reset();
});

test('loadState returns the payload', (t) => {
getItemStub.returns(testPayload);
t.deepEqual(loadState(), testData);
});

test('loadState returns undefined if no state found', (t) => {
getItemStub.returns(null);
t.is(loadState(), undefined);
});

test('loadState returns undefined if error in serializing JSON or accessing localStorage', (t) => {
getItemStub.throws(new Error());
t.is(loadState(), undefined);
});

test('saveState saves the payload to localStorage', (t) => {
saveState(testData);
t.plan(2);
t.true(setItemStub.called);
t.is(setItemStub.lastCall.args[1], testPayload);
});

test('saveState returns undefined if error in parsing JSON or accessing localStorage', (t) => {
setItemStub.throws(new Error());
saveState(testData);
t.is(saveState(), undefined);
});
3 changes: 2 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable import/no-extraneous-dependencies */
const { HotModuleReplacementPlugin } = require('webpack');
const { HotModuleReplacementPlugin, DefinePlugin } = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
Expand All @@ -26,6 +26,7 @@ module.exports = {
},

plugins: [
new DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('development') } }),
new HtmlWebpackPlugin({ template: `${__dirname}/app/index.tmpl.html` }),
new HotModuleReplacementPlugin(),
],
Expand Down

0 comments on commit 90fac36

Please sign in to comment.