Skip to content

Commit cb55a99

Browse files
committed
Compose function now has it's own tests (that handle fbConfig not being complete).
1 parent cc59d92 commit cb55a99

File tree

5 files changed

+104
-28
lines changed

5 files changed

+104
-28
lines changed

src/helpers.js

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
import { size, map } from 'lodash'
22

3-
const fixPath = path => ((path.substring(0, 1) === '/') ? '' : '/') + path
4-
3+
/**
4+
* @description Fix path by adding "/" to path if needed
5+
* @param {String} path - Path string to fix
6+
* @return {String} path - Fixed path
7+
*/
8+
export const fixPath = path =>
9+
((path.substring(0, 1) === '/') ? '' : '/') + path
10+
11+
/**
12+
* @description Convert Immutable Map to a Javascript object
13+
* @param {Object} data - Immutable Map to be converted to JS object
14+
* @return {Object} data - Javascript version of Immutable Map
15+
*/
516
export const toJS = data => {
617
if (data && data.toJS) {
718
return data.toJS()
@@ -10,6 +21,11 @@ export const toJS = data => {
1021
return data
1122
}
1223

24+
/**
25+
* @description Convert parameter from Immutable Map to a Javascript object
26+
* @param {Object} data - Immutable Map to be converted to JS object
27+
* @return {Object} data - Javascript version of Immutable Map
28+
*/
1329
export const pathToJS = (data, path, notSetValue) => {
1430
if (!data) {
1531
return notSetValue
@@ -24,6 +40,13 @@ export const pathToJS = (data, path, notSetValue) => {
2440
return data
2541
}
2642

43+
/**
44+
* @description Convert parameter under "data" path of Immutable Map to a Javascript object
45+
* @param {Object} data - Immutable Map to be converted to JS object
46+
* @param {String} path - Path of parameter to load
47+
* @param {Object|String|Boolean} notSetValue - Value to return if value is not found
48+
* @return {Object} data - Javascript version of Immutable Map
49+
*/
2750
export const dataToJS = (data, path, notSetValue) => {
2851
if (!data) {
2952
return notSetValue
@@ -40,6 +63,14 @@ export const dataToJS = (data, path, notSetValue) => {
4063
return data
4164
}
4265

66+
/**
67+
* @description Load custom object from within store
68+
* @param {Object} data - Immutable Map from store to be converted to JS object
69+
* @param {String} path - Path of parameter to load
70+
* @param {String} customPath - Part of store from which to load
71+
* @param {Object|String|Boolean} notSetValue - Value to return if value is not found
72+
* @return {Object} data - Javascript version of custom path within Immutable Map
73+
*/
4374
export const customToJS = (data, path, custom, notSetValue) => {
4475
if (!(data && data.getIn)) {
4576
return notSetValue
@@ -56,8 +87,14 @@ export const customToJS = (data, path, custom, notSetValue) => {
5687
return data
5788
}
5889

90+
/**
91+
* @description Convert Immutable Map to a Javascript object
92+
* @param {Object} snapshot - Snapshot from store
93+
* @param {String} path - Path of snapshot to load
94+
* @return {Object} notSetValue - Value to return if snapshot is not found
95+
*/
5996
export const snapshotToJS = (snapshot, path, notSetValue) => {
60-
if (!(snapshot && snapshot.getIn)) {
97+
if (!snapshot) {
6198
return notSetValue
6299
}
63100

@@ -72,6 +109,11 @@ export const snapshotToJS = (snapshot, path, notSetValue) => {
72109
return snapshot
73110
}
74111

112+
/**
113+
* @description Detect whether items are loaded yet or not
114+
* @param {Object} item - Item to check loaded status of. A comma seperated list is also acceptable.
115+
* @return {Boolean} isLoaded - Whether or not item is loaded
116+
*/
75117
export const isLoaded = function () {
76118
if (!arguments || !arguments.length) {
77119
return true
@@ -80,8 +122,21 @@ export const isLoaded = function () {
80122
return map(arguments, a => a !== undefined).reduce((a, b) => a && b)
81123
}
82124

125+
/**
126+
* @description Detect whether items are empty or not
127+
* @param {Object} item - Item to check loaded status of. A comma seperated list is also acceptable.
128+
* @return {Boolean} isEmpty - Whether or not item is empty
129+
*/
83130
export const isEmpty = data => {
84131
return !(data && size(data))
85132
}
86133

87-
export default { toJS, pathToJS, dataToJS, snapshotToJS, customToJS, isLoaded, isEmpty }
134+
export default {
135+
toJS,
136+
pathToJS,
137+
dataToJS,
138+
snapshotToJS,
139+
customToJS,
140+
isLoaded,
141+
isEmpty
142+
}

src/utils/auth.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { capitalize, isArray, isString } from 'lodash'
22
import { supportedAuthProviders } from '../constants'
3+
34
/**
45
* @description Get correct login method and params order based on provided credentials
56
* @param {Object} firebase - Internal firebase object

test/unit/compose.spec.js

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,40 @@
11
/* global describe expect it */
2-
import compose from '../../src/compose'
2+
import { omit } from 'lodash'
3+
import { createStore, combineReducers, compose } from 'redux'
4+
import composeFunc from '../../src/compose'
35
const exampleData = { data: { some: 'data' } }
6+
const reducer = () => console.log('reducer', {})
7+
const generateCreateStore = (params) =>
8+
compose(composeFunc(
9+
omit(fbConfig, params),
10+
{ userProfile: 'users', enableLogging: true }
11+
))(createStore)
412

5-
// TODO: Use immutable object so functions exist on object
613
describe('Compose', () => {
714
it('is a function', () => {
8-
expect(compose).to.be.a.function
15+
expect(composeFunc).to.be.a.function
916
})
1017
it('returns an object', () => {
11-
expect(compose(fbConfig)).to.be.an.object
18+
expect(composeFunc(fbConfig)).to.be.a.function
1219
})
20+
it('allows enabling of Firebase database logging', () => {
21+
const createStoreWithFirebase = compose(composeFunc(
22+
fbConfig,
23+
{ userProfile: 'users', enableLogging: true }
24+
))(createStore)
25+
expect(createStoreWithFirebase(reducer)).to.be.an.object
26+
})
27+
describe('throws for missing fbConfig parameters', () => {
28+
29+
it('databaseURL', () => {
30+
expect(() => generateCreateStore('databaseURL')(reducer)).to.throw('Firebase databaseURL is required')
31+
})
32+
it('authDomain', () => {
33+
expect(() => generateCreateStore('authDomain')(reducer)).to.throw('Firebase authDomain is required')
34+
})
35+
it('apiKey', () => {
36+
expect(() => generateCreateStore('apiKey')(reducer)).to.throw('Firebase apiKey is required')
37+
})
38+
})
39+
1340
})

test/unit/connect.spec.js

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,6 @@ describe('Connect', () => {
4141
: prev
4242
}
4343

44-
it('throws for invalid databaseURL', () => {
45-
const createStoreWithMiddleware = compose(
46-
reduxFirebase({}, { userProfile: 'users' }),
47-
typeof window === 'object' && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : f => f
48-
)(createStore)
49-
50-
expect(createStoreWithMiddleware).to.throw(Error)
51-
})
52-
53-
it('throws for invalid authDomain', () => {
54-
const createStoreWithMiddleware = compose(
55-
reduxFirebase({ databaseURL }, { userProfile: 'users' }),
56-
typeof window === 'object' && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : f => f
57-
)(createStore)
58-
59-
expect(createStoreWithMiddleware).to.throw(Error)
60-
})
6144

6245
it('should receive the store in the context', () => {
6346
const createStoreWithMiddleware = compose(
@@ -80,8 +63,10 @@ describe('Connect', () => {
8063
)
8164

8265
const container = TestUtils.findRenderedComponentWithType(tree, Container)
66+
container.setState({
67+
testState: 'somethingElse'
68+
})
8369
expect(container.context.store).to.equal(store)
8470
})
8571

86-
8772
})

test/unit/helpers.spec.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,24 @@ describe('Helpers:', () => {
7878
expect(helpers).to.respondTo('snapshotToJS')
7979
})
8080
it('passes notSetValue', () => {
81-
expect(helpers.snapshotToJS({}, '/some', exampleData))
81+
const fakeState = { }
82+
expect(helpers.snapshotToJS(fakeState, '/some', exampleData))
8283
.to
83-
.equal(exampleData)
84+
.equal(fakeState)
8485
})
8586
it('gets data from state', () => {
8687
const path = 'some'
8788
expect(helpers.snapshotToJS(exampleState, path, exampleData))
8889
.to
8990
.equal(exampleData.snapshot[path])
9091
})
92+
it('returns snapshot for non-immutable', () => {
93+
const path = 'some'
94+
const fakeState = { }
95+
expect(helpers.snapshotToJS(fakeState, path, exampleData))
96+
.to
97+
.equal(fakeState)
98+
})
9199
})
92100

93101
describe('isLoaded', () => {

0 commit comments

Comments
 (0)