diff --git a/examples/simple/src/TodoItem.js b/examples/simple/src/TodoItem.js
index eca0e03ba..044c26d21 100644
--- a/examples/simple/src/TodoItem.js
+++ b/examples/simple/src/TodoItem.js
@@ -1,5 +1,5 @@
import React, { PropTypes, Component } from 'react'
-import { firebase } from 'redux-firebasev3'
+import { firebase } from 'react-redux-firebase'
import './Todo.css'
diff --git a/examples/simple/src/config.js b/examples/simple/src/config.js
index b85e9f30d..d690423f1 100644
--- a/examples/simple/src/config.js
+++ b/examples/simple/src/config.js
@@ -1,7 +1,7 @@
export const firebase = {
apiKey: 'AIzaSyCTUERDM-Pchn_UDTsfhVPiwM4TtNIxots',
- authDomain: 'redux-firebasev3.firebaseapp.com',
- databaseURL: 'https://redux-firebasev3.firebaseio.com'
+ authDomain: 'react-redux-firebase.firebaseapp.com',
+ databaseURL: 'https://react-redux-firebase.firebaseio.com'
}
export default { firebase }
diff --git a/examples/simple/src/reducer.js b/examples/simple/src/reducer.js
index e621b1b20..184cc14a5 100644
--- a/examples/simple/src/reducer.js
+++ b/examples/simple/src/reducer.js
@@ -1,5 +1,5 @@
import { combineReducers } from 'redux'
-import { firebaseStateReducer as firebase } from 'redux-firebasev3'
+import { firebaseStateReducer as firebase } from 'react-redux-firebase'
const rootReducer = combineReducers({
firebase
diff --git a/examples/simple/src/store.js b/examples/simple/src/store.js
index 3e0a5cca4..4c0d8e4b5 100644
--- a/examples/simple/src/store.js
+++ b/examples/simple/src/store.js
@@ -1,7 +1,7 @@
import { createStore, compose } from 'redux'
import rootReducer from './reducer'
import { firebase as fbConfig } from './config'
-import { reduxFirebase } from 'redux-firebase'
+import { reduxFirebase } from 'react-redux-firebase'
export default function configureStore (initialState, history) {
const createStoreWithMiddleware = compose(
diff --git a/package.json b/package.json
index 2380a2195..107f10b45 100644
--- a/package.json
+++ b/package.json
@@ -1,14 +1,10 @@
{
"name": "react-redux-firebase",
- "version": "1.0.0",
+ "version": "1.0.1",
"description": "A Higher Order Component to use Firebase version 3 with Redux",
"main": "dist/index.js",
"module": "src/index.js",
"jsnext:main": "src/index.js",
- "files": [
- "dist",
- "src"
- ],
"scripts": {
"build": "babel src --out-dir dist",
"build-dev": "babel src --out-dir dist --watch --src-maps inline",
@@ -47,28 +43,8 @@
"url": "https://github.com/tiberiuc"
}
],
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git+https://github.com/prescottprue/react-redux-firebase.git"
- },
- "bugs": {
- "url": "https://github.com/prescottprue/react-redux-firebase/issues"
- },
- "homepage": "https://github.com/prescottprue/react-redux-firebase#readme",
- "keywords": [
- "firebase",
- "redux",
- "react",
- "react-redux",
- "redux-firebase",
- "react",
- "babel",
- "hoc",
- "react-redux-firebase"
- ],
"dependencies": {
- "firebase": "^3.4.1",
+ "firebase": "^3.5.0",
"immutable": "^3.8.1",
"jwt-decode": "^2.1.0",
"lodash": "^4.16.4"
@@ -85,6 +61,7 @@
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-es6-promise": "^1.0.0",
"babel-plugin-lodash": "^3.2.9",
+ "babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.16.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-1": "^6.16.0",
@@ -98,10 +75,37 @@
"eslint-plugin-react": "^6.4.1",
"eslint-plugin-standard": "^2.0.1",
"isparta": "^4.0.0",
+ "jsdom": "^9.8.0",
"mocha": "^3.1.2",
+ "react-addons-test-utils": "^15.3.2",
+ "react-dom": "^15.3.2",
"rimraf": "^2.5.4"
},
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/prescottprue/react-redux-firebase.git"
+ },
+ "bugs": {
+ "url": "https://github.com/prescottprue/react-redux-firebase/issues"
+ },
+ "homepage": "https://github.com/prescottprue/react-redux-firebase#readme",
+ "keywords": [
+ "firebase",
+ "redux",
+ "react",
+ "react-redux",
+ "redux-firebase",
+ "react",
+ "babel",
+ "hoc",
+ "react-redux-firebase"
+ ],
"npmName": "react-redux-firebase",
+ "files": [
+ "dist",
+ "src"
+ ],
"npmFileMap": [
{
"basePath": "/dist/",
diff --git a/src/actions/query.js b/src/actions/query.js
index 6bb178c9a..0471df4a0 100644
--- a/src/actions/query.js
+++ b/src/actions/query.js
@@ -6,7 +6,7 @@ import {
import { map, filter, isString, isObject } from 'lodash'
const getWatchPath = (event, path) =>
- event + ':' + ((path.substring(0, 1) === '/') ? '' : '/') + path
+ `${event}:${((path.substring(0, 1) === '/') ? '' : '/')}${path}`
/**
* @description Set a new watcher
@@ -16,7 +16,7 @@ const getWatchPath = (event, path) =>
* @param {String} queryId - Id of query
*/
const setWatcher = (firebase, event, path, queryId = undefined) => {
- const id = (queryId) ? event + ':/' + queryId : getWatchPath(event, path)
+ const id = queryId ? `${event}:/${queryId}` : getWatchPath(event, path)
if (firebase._.watchers[id]) {
firebase._.watchers[id]++
@@ -35,7 +35,7 @@ const setWatcher = (firebase, event, path, queryId = undefined) => {
* @param {String} queryId - Id of query
*/
const getWatcherCount = (firebase, event, path, queryId = undefined) => {
- const id = (queryId) ? event + ':/' + queryId : getWatchPath(event, path)
+ const id = queryId ? `${event}:/${queryId}` : getWatchPath(event, path)
return firebase._.watchers[id]
}
@@ -108,7 +108,7 @@ export const watchEvent = (firebase, dispatch, event, path, dest, onlyLastEvent
queryParams = pathSplitted[1].split('&')
}
- const watchPath = (!dest) ? path : path + '@' + dest
+ const watchPath = !dest ? path : `${path}@${dest}`
const counter = getWatcherCount(firebase, event, watchPath, queryId)
if (counter > 0) {
@@ -146,7 +146,7 @@ export const watchEvent = (firebase, dispatch, event, path, dest, onlyLastEvent
if (isQuery) {
let doNotParse = false
- queryParams.forEach((param) => {
+ queryParams.forEach(param => {
param = param.split('=')
switch (param[0]) {
case 'orderByValue':
@@ -197,14 +197,18 @@ export const watchEvent = (firebase, dispatch, event, path, dest, onlyLastEvent
}
const runQuery = (q, e, p, params) => {
+ // Handle once queries
if (e === 'once') {
- q.once('value').then(snapshot => dispatch({type: SET, path, data: snapshot.val()}))
- return;
+ return q.once('value')
+ .then(snapshot =>
+ dispatch({ type: SET, path, data: snapshot.val() })
+ )
}
+ // Handle all other queries
q.on(e, snapshot => {
let data = (e === 'child_removed') ? undefined : snapshot.val()
- const resultPath = dest || (e === 'value') ? p : p + '/' + snapshot.key
+ const resultPath = dest || (e === 'value') ? p : `${p}/${snapshot.key}`
if (dest && e !== 'child_removed') {
data = {
@@ -213,8 +217,10 @@ export const watchEvent = (firebase, dispatch, event, path, dest, onlyLastEvent
}
}
- const populates = filter(params, (param) => params.indexOf('populate') > -1)
- .map(p => p.split('=')[1])
+ // Get list of populates
+ const populates = filter(params, param =>
+ params.indexOf('populate') !== -1
+ ).map(p => p.split('=')[1])
// Dispatch standard if no populates
if (!populates || !populates.length) {
@@ -241,9 +247,15 @@ export const watchEvent = (firebase, dispatch, event, path, dest, onlyLastEvent
if (!item[paramToPopulate]) {
return Object.assign(item, { _key: key })
}
+
+ // TODO: Handle populating a list
return !isString(item[paramToPopulate])
// Parameter to be populated is not an id
- ? Promise.reject(`Population id is not a string.\n Type: ${typeof item[paramToPopulate]}\n Id: ${JSON.stringify(item[paramToPopulate])}`)
+ ? Promise.reject(`
+ Population id is not a string.\n
+ Type: ${typeof item[paramToPopulate]}\n
+ Id: ${JSON.stringify(item[paramToPopulate])}
+ `)
: listRef.child(item[paramToPopulate])
.once('value')
.then(snap =>
@@ -302,7 +314,9 @@ export const unWatchEvent = (firebase, event, path, queryId = undefined) =>
* @param {Array} events - List of events for which to add watchers
*/
export const watchEvents = (firebase, dispatch, events) =>
- events.forEach(event => watchEvent(firebase, dispatch, event.name, event.path))
+ events.forEach(event =>
+ watchEvent(firebase, dispatch, event.name, event.path)
+ )
/**
* @description Remove watchers from a list of events
@@ -310,6 +324,8 @@ export const watchEvents = (firebase, dispatch, events) =>
* @param {Array} events - List of events for which to remove watchers
*/
export const unWatchEvents = (firebase, events) =>
- events.forEach(event => unWatchEvent(firebase, event.name, event.path))
+ events.forEach(event =>
+ unWatchEvent(firebase, event.name, event.path)
+ )
export default { watchEvents, unWatchEvents }
diff --git a/test/setup.js b/test/setup.js
index 1c61acc37..640042158 100644
--- a/test/setup.js
+++ b/test/setup.js
@@ -4,3 +4,9 @@ process.env.NODE_ENV = 'test'
var chai = global.chai = require('chai')
var expect = global.expect = chai.expect
+
+import { jsdom } from 'jsdom'
+
+global.document = jsdom('')
+global.window = document.defaultView
+global.navigator = global.window.navigator
diff --git a/test/unit/actions/query.spec.js b/test/unit/actions/query.spec.js
new file mode 100644
index 000000000..a2e2f5e42
--- /dev/null
+++ b/test/unit/actions/query.spec.js
@@ -0,0 +1,119 @@
+/* global describe expect it beforeEach */
+import {
+ watchEvent,
+ unWatchEvent,
+ watchEvents,
+ unWatchEvents
+} from '../../../src/actions/query'
+import Firebase from 'firebase'
+const apiKey = 'AIzaSyCTUERDM-Pchn_UDTsfhVPiwM4TtNIxots'
+const authDomain = 'redux-firebasev3.firebaseapp.com'
+const databaseURL = 'https://redux-firebasev3.firebaseio.com'
+const testFbConfig = {
+ databaseURL,
+ apiKey,
+ authDomain
+}
+let firebase
+describe('query actions', () => {
+ describe('watchEvent', () => {
+ beforeEach(() => {
+ // TODO: Set up a firebase (real for now, fake later) and store (for dispatch)
+ // Initialize Firebase
+ try {
+ Firebase.initializeApp(testFbConfig)
+ } catch (err) {}
+
+ firebase = Object.defineProperty(Firebase, '_', {
+ value: {
+ watchers: {},
+ config: testFbConfig,
+ authUid: null
+ },
+ writable: true,
+ enumerable: true,
+ configurable: true
+ })
+ })
+ it('is exported', () => {
+ expect(watchEvent).to.be.a.function
+ })
+ it('runs given basic params', () => {
+ watchEvent(firebase, () => {}, 'once', 'projects', 'projects')
+ })
+
+ describe.skip('populate', () => {
+ it('populates id with string', () => {
+ // TODO: Confirm that SET action is dispatched with populated data
+ })
+ it('populates id with object', () => {
+ // TODO: Confirm that SET action is dispatched with populated data
+ })
+ it('handles invalid population id', () => {
+ // TODO: Confirm that SET action is dispatched with populated data
+ })
+ })
+ describe.skip('query types', () => {
+ it('once query', () => {
+ // TODO: Test that SET action is dispatched with data
+ })
+ it('on query', () => {
+ // TODO: Confirm that stubbed version of firebase is called
+ // TODO: Confirm that SET action is dispatched correctly
+ })
+ })
+ describe.skip('filters', () => {
+ it('orderByValue', () => {
+
+ })
+ it('orderByPriority', () => {
+
+ })
+ it('orderByKey', () => {
+
+ })
+ it('orderByChild', () => {
+
+ })
+ it('limitToFirst', () => {
+
+ })
+ it('limitToLast', () => {
+
+ })
+ it('equalTo', () => {
+
+ })
+ it('startAt', () => {
+
+ })
+ it('endAt', () => {
+
+ })
+ })
+ })
+ describe('unWatchEvent', () => {
+ it('is exported', () => {
+ expect(unWatchEvent).to.be.a.function
+ })
+ it('runs given basic params', () => {
+ unWatchEvent(firebase, () => {}, 'once', 'projects', 'projects')
+ })
+ })
+ describe('watchEvents', () => {
+ it('is exported', () => {
+ expect(watchEvents).to.be.a.function
+ })
+ it('runs given basic params', () => {
+ watchEvents(firebase, () => {}, [{name: 'once', path: 'test'}])
+ })
+ })
+ describe('unWatchEvents', () => {
+ it('is exported', () => {
+ expect(unWatchEvents).to.be.a.function
+ })
+ it('runs given basic params', () => {
+ unWatchEvents(firebase, [{name: 'value', path: 'test'}])
+ })
+ })
+})
diff --git a/test/unit/connect.spec.js b/test/unit/connect.spec.js
new file mode 100644
index 000000000..eba5a9e56
--- /dev/null
+++ b/test/unit/connect.spec.js
@@ -0,0 +1,87 @@
+import React, { createClass, Children, PropTypes, Component } from 'react'
+import ReactDOM from 'react-dom'
+import connect from '../../src/connect'
+import reduxFirebase from '../../src/compose'
+import TestUtils from 'react-addons-test-utils'
+import { createStore, compose, combineReducers } from 'redux'
+
+const apiKey = 'AIzaSyCTUERDM-Pchn_UDTsfhVPiwM4TtNIxots'
+const authDomain = 'redux-firebasev3.firebaseapp.com'
+const databaseURL = 'https://redux-firebasev3.firebaseio.com'
+const testFbConfig = {
+ databaseURL,
+ apiKey,
+ authDomain
+}
+
+describe('Connect', () => {
+ class Passthrough extends Component {
+ render () {
+ return
{JSON.stringify(this.props)}
+ }
+ }
+
+ class ProviderMock extends Component {
+ getChildContext () {
+ return { store: this.props.store }
+ }
+
+ render () {
+ return Children.only(this.props.children)
+ }
+ }
+
+ ProviderMock.childContextTypes = {
+ store: PropTypes.object.isRequired
+ }
+
+ function stringBuilder (prev = '', action) {
+ return action.type === 'APPEND'
+ ? prev + action.body
+ : prev
+ }
+
+ it('throws for invalid databaseURL', () => {
+ const createStoreWithMiddleware = compose(
+ reduxFirebase({}, { userProfile: 'users' }),
+ typeof window === 'object' && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : f => f
+ )(createStore)
+
+ expect(createStoreWithMiddleware).to.throw(Error)
+ })
+
+ it('throws for invalid authDomain', () => {
+ const createStoreWithMiddleware = compose(
+ reduxFirebase({ databaseURL }, { userProfile: 'users' }),
+ typeof window === 'object' && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : f => f
+ )(createStore)
+
+ expect(createStoreWithMiddleware).to.throw(Error)
+ })
+
+ it('should receive the store in the context', () => {
+ const createStoreWithMiddleware = compose(
+ reduxFirebase(testFbConfig, { userProfile: 'users' }),
+ typeof window === 'object' && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : f => f
+ )(createStore)
+ const store = createStoreWithMiddleware(combineReducers({ test: (state = {}) => state }))
+
+ @connect()
+ class Container extends Component {
+ render() {
+ return
+ }
+ }
+
+ const tree = TestUtils.renderIntoDocument(
+
+
+
+ )
+
+ const container = TestUtils.findRenderedComponentWithType(tree, Container)
+ expect(container.context.store).to.equal(store)
+ })
+
+
+})
diff --git a/test/unit/helpers.spec.js b/test/unit/helpers.spec.js
index 1a43f05f3..1e377d997 100644
--- a/test/unit/helpers.spec.js
+++ b/test/unit/helpers.spec.js
@@ -1,6 +1,7 @@
/* global describe expect it */
import helpers from '../../src/helpers'
-const exampleData = { data: { some: 'data' }}
+const exampleData = { data: { some: 'data' } }
+
describe('helpers', () => {
it('toJS', () => {
describe('exists', () => {
diff --git a/test/unit/library.spec.js b/test/unit/library.spec.js
index 151743fe3..ebb587387 100644
--- a/test/unit/library.spec.js
+++ b/test/unit/library.spec.js
@@ -1,7 +1,7 @@
/* global describe expect it */
import src from '../../src'
-describe('redux-firebasev3', () => {
+describe('module', () => {
describe('exports', () => {
it('firebase', () => {
expect(src).to.respondTo('firebase')