diff --git a/__mocks__/react-native-firebase.js b/__mocks__/react-native-firebase.js index 79ae2fd..44777dd 100644 --- a/__mocks__/react-native-firebase.js +++ b/__mocks__/react-native-firebase.js @@ -1,7 +1,7 @@ 'use strict' export class Database { - ref = (path) => { + ref = path => { if (!this[path]) { this[path] = new Reference(path) } @@ -12,7 +12,7 @@ export class Database { export class Reference { constructor(path) { this.path = path - this.snap = { val: () => this._val()} + this.snap = { val: () => this._val() } this.data = null } @@ -21,7 +21,7 @@ export class Reference { }) once = jest.fn((param, callback) => { - const promise = new Promise ((resolve, reject) => { + const promise = new Promise((resolve, reject) => { if (callback) { callback(this.snap) resolve() @@ -34,7 +34,7 @@ export class Reference { }) on = jest.fn((param, callback) => { - const promise = new Promise ((resolve, reject) => { + const promise = new Promise((resolve, reject) => { if (callback) { callback(this.snap) resolve() @@ -52,7 +52,7 @@ export class Reference { return promise }) - update = jest.fn((data) => { + update = jest.fn(data => { const promise = Promise.resolve() RNFirebase.promises.push(promise) return promise diff --git a/__tests__/actions.js b/__tests__/actions.js index 13f0510..889ab71 100644 --- a/__tests__/actions.js +++ b/__tests__/actions.js @@ -1,17 +1,9 @@ import * as actions from '../actions' import * as types from '../types' +import firebase from '../firebase' import { metaTypes } from '../types' -import RNFirebase from 'react-native-firebase' -import configureMockStore from 'redux-mock-store' -import { getInitialState } from '../reducer' - -const mockStore = configureMockStore() describe('firebase actions', () => { - beforeEach(() => { - RNFirebase.reset() - }) - test(types.firebase.FIREBASE_LISTEN_REQUESTED, () => { const ref = firebase.database().ref('someRef') const expectedAction = { diff --git a/__tests__/sagas.js b/__tests__/sagas.js index 0ce40f1..3ee0796 100644 --- a/__tests__/sagas.js +++ b/__tests__/sagas.js @@ -1,20 +1,10 @@ import * as sagas from '../sagas' import * as types from '../types' import firebase from '../firebase' -import { - all, - put, - takeEvery, - take, - call, - fork, - cancel, - flush, - cancelled, -} from 'redux-saga/effects' -import { cloneableGenerator, createMockTask } from 'redux-saga/utils' import * as actions from '../actions' import { metaTypes, eventTypes } from '../types' +import { cloneableGenerator, createMockTask } from 'redux-saga/utils' +import { put, take, call, fork, cancel, flush } from 'redux-saga/effects' describe('database saga', () => { test(`watchUpdateRequested ${metaTypes.userContacts}`, () => { diff --git a/patterns/listener_actions.js b/patterns/listener_actions.js index 38f5ec2..4da0e06 100644 --- a/patterns/listener_actions.js +++ b/patterns/listener_actions.js @@ -1,3 +1,6 @@ +import * as types from './types' +import { metaTypes } from './types' + export function firebaseListenRequested(ref, metaType) { return { type: types.firebase.FIREBASE_LISTEN_REQUESTED, @@ -30,22 +33,6 @@ export function firebaseListenChildAdded(id, value, metaType) { } } -export function firebaseListenChildChanged(id, value, metaType) { - return { - type: types.firebase.FIREBASE_LISTEN_CHILD_CHANGED, - payload: { id, value }, - meta: { type: metaType }, - } -} - -export function firebaseListenChildRemoved(id, metaType) { - return { - type: types.firebase.FIREBASE_LISTEN_CHILD_REMOVED, - payload: { id }, - meta: { type: metaType }, - } -} - export function firebaseListenRemoved(clearItems, metaType) { return { type: types.firebase.FIREBASE_LISTEN_REMOVED, @@ -61,10 +48,3 @@ export function firebaseRemoveListenerRequested(clearItems, metaType) { meta: { type: metaType }, } } - -export function firebaseRemoveAllListenersRequested() { - return { - type: types.firebase.FIREBASE_REMOVE_ALL_LISTENERS_REQUESTED, - payload: { clearItems: true }, - } -} diff --git a/patterns/listener_reducer.js b/patterns/listener_reducer.js index 87aab53..539564d 100644 --- a/patterns/listener_reducer.js +++ b/patterns/listener_reducer.js @@ -1,3 +1,7 @@ +import * as types from './types' +import { metaTypes } from './types' +... + [types.firebase.FIREBASE_LISTEN_REQUESTED](state, action) { const property = action.meta.type const propertyState = state[property] @@ -45,32 +49,6 @@ } return newState }, -[types.firebase.FIREBASE_LISTEN_CHILD_CHANGED](state, action) { - const property = action.meta.type - const propertyState = state[property] - const items = { - ...propertyState.items, - [action.payload.id]: action.payload.value, - } - - let newState = { - ...state, - [property]: { ...propertyState, inProgress: false, error: '', items }, - } - return newState -}, -[types.firebase.FIREBASE_LISTEN_CHILD_REMOVED](state, action) { - const property = action.meta.type - const propertyState = state[property] - const items = { ...propertyState.items } - delete items[action.payload.id] - - let newState = { - ...state, - [property]: { ...propertyState, inProgress: false, error: '', items }, - } - return newState -}, [types.firebase.FIREBASE_LISTEN_REMOVED](state, action) { const property = action.meta.type const propertyState = state[property] diff --git a/patterns/listener_sagas.js b/patterns/listener_sagas.js index c4631d5..0c035f4 100644 --- a/patterns/listener_sagas.js +++ b/patterns/listener_sagas.js @@ -1,3 +1,10 @@ +import * as types from './types' +import { metaTypes, eventTypes } from './types' +import * as actions from './actions' +import firebase from './firebase' +import { eventChannel, buffers } from 'redux-saga' +import { put, take, call, fork, cancel, flush } from 'redux-saga/effects' + export function* watchListener(metaType) { while (true) { const listenRequestAction = yield take( @@ -13,20 +20,12 @@ export function* watchListener(metaType) { const action = yield take([ types.firebase.FIREBASE_REMOVE_LISTENER_REQUESTED, types.firebase.FIREBASE_LISTEN_REQUESTED, - types.firebase.FIREBASE_REMOVE_ALL_LISTENERS_REQUESTED, ]) - if ( - action.type === - types.firebase.FIREBASE_REMOVE_ALL_LISTENERS_REQUESTED || - action.meta.type === metaType - ) { + if (action.meta.type === metaType) { yield cancel(task) yield put( - FirebaseActions.firebaseListenRemoved( - !!action.payload.clearItems, - metaType - ) + actions.firebaseListenRemoved(!!action.payload.clearItems, metaType) ) if (action.type === types.firebase.FIREBASE_LISTEN_REQUESTED) { @@ -53,19 +52,6 @@ export function createEventChannel(ref) { value: snap.val(), }) }) - - ref.on('child_changed', snap => { - const val = snap.val() - emit({ - eventType: eventTypes.CHILD_CHANGED, - key: snap.key, - value: snap.val(), - }) - }) - - ref.on('child_removed', snap => { - emit({ eventType: eventTypes.CHILD_REMOVED, key: snap.key }) - }) return () => { ref.off() } @@ -81,34 +67,17 @@ export function* getDataAndListenToChannel(ref, metaType) { yield flush(chan) const val = snap.val() const value = val ? val : {} - yield put(FirebaseActions.firebaseListenFulfilled(value, metaType)) + yield put(actions.firebaseListenFulfilled(value, metaType)) } catch (error) { - yield put(FirebaseActions.firebaseListenRejected(error, metaType)) + yield put(actions.firebaseListenRejected(error, metaType)) } while (true) { const data = yield take(chan) - yield put(getUpdateAction(data, metaType)) + yield put( + actions.firebaseListenChildAdded(data.key, data.value, metaType) + ) } } finally { chan.close() } } - -export function getUpdateAction(data, metaType) { - switch (data.eventType) { - case eventTypes.CHILD_ADDED: - return FirebaseActions.firebaseListenChildAdded( - data.key, - data.value, - metaType - ) - case eventTypes.CHILD_CHANGED: - return FirebaseActions.firebaseListenChildChanged( - data.key, - data.value, - metaType - ) - case eventTypes.CHILD_REMOVED: - return FirebaseActions.firebaseListenChildRemoved(data.key, metaType) - } -} diff --git a/patterns/remove_actions.js b/patterns/remove_actions.js index 6d9e605..e6676d0 100644 --- a/patterns/remove_actions.js +++ b/patterns/remove_actions.js @@ -1,3 +1,6 @@ +import * as types from './types' +import { metaTypes } from './types' + export function firebaseRemoveRequested(payload, metaType) { return { type: types.firebase.FIREBASE_REMOVE_REQUESTED, diff --git a/patterns/remove_reducer.js b/patterns/remove_reducer.js index 8d3b841..4e7d96f 100644 --- a/patterns/remove_reducer.js +++ b/patterns/remove_reducer.js @@ -1,3 +1,8 @@ +import * as types from './types' +import { metaTypes } from './types' + +... + [types.firebase.FIREBASE_REMOVE_REQUESTED](state, action) { const property = action.meta.type let newState = { ...state, [property]: { inProgress: true, error: '' } } diff --git a/patterns/remove_sagas.js b/patterns/remove_sagas.js index fd30159..4ffd475 100644 --- a/patterns/remove_sagas.js +++ b/patterns/remove_sagas.js @@ -1,3 +1,9 @@ +import * as types from './types' +import { metaTypes } from './types' +import * as actions from './actions' +import firebase from './firebase' +import { put, take, call, fork } from 'redux-saga/effects' + export function* watchRemoveRequested() { while (true) { const action = yield take(types.firebase.FIREBASE_REMOVE_REQUESTED) @@ -23,8 +29,8 @@ export function* removeItem(path, metaType) { try { const ref = firebase.database().ref(path) yield call([ref, ref.remove]) - yield put(FirebaseActions.firebaseRemoveFulfilled(metaType)) + yield put(actions.firebaseRemoveFulfilled(metaType)) } catch (error) { - yield put(FirebaseActions.firebaseRemoveRejected(error, metaType)) + yield put(actions.firebaseRemoveRejected(error, metaType)) } } diff --git a/patterns/update_action_test.js b/patterns/update_action_test.js index ac223aa..7c93b5e 100644 --- a/patterns/update_action_test.js +++ b/patterns/update_action_test.js @@ -1,3 +1,7 @@ +import * as actions from '../actions' +import * as types from '../types' +import { metaTypes } from '../types' + test('updateUserContactsRequested', () => { const uid = '1' const contactId = '123' diff --git a/patterns/update_actions.js b/patterns/update_actions.js index 036413c..d78323a 100644 --- a/patterns/update_actions.js +++ b/patterns/update_actions.js @@ -1,3 +1,6 @@ +import * as types from './types' +import { metaTypes } from './types' + export function firebaseUpdateRequested(payload, metaType) { return { type: types.firebase.FIREBASE_UPDATE_REQUESTED, diff --git a/patterns/update_reducer.js b/patterns/update_reducer.js index 7fafc37..3a5ffb4 100644 --- a/patterns/update_reducer.js +++ b/patterns/update_reducer.js @@ -1,3 +1,8 @@ +import * as types from './types' +import { metaTypes } from './types' + +... + [types.firebase.FIREBASE_UPDATE_REQUESTED](state, action) { const property = action.meta.type let newState = { ...state, [property]: { inProgress: true, error: '' } } diff --git a/patterns/update_sagas.js b/patterns/update_sagas.js index d511feb..0beb895 100644 --- a/patterns/update_sagas.js +++ b/patterns/update_sagas.js @@ -1,3 +1,9 @@ +import * as types from './types' +import { metaTypes } from './types' +import * as actions from './actions' +import firebase from './firebase' +import { put, take, call, fork } from 'redux-saga/effects' + export function* watchUpdateRequested() { while (true) { const action = yield take(types.firebase.FIREBASE_UPDATE_REQUESTED) @@ -18,9 +24,9 @@ export function* updateItems(updates, metaType) { try { const ref = firebase.database().ref() yield call([ref, ref.update], updates) - yield put(FirebaseActions.firebaseUpdateFulfilled(metaType)) + yield put(actions.firebaseUpdateFulfilled(metaType)) } catch (error) { - yield put(FirebaseActions.firebaseUpdateRejected(error, metaType)) + yield put(actions.firebaseUpdateRejected(error, metaType)) } } diff --git a/patterns/update_sagas_test.js b/patterns/update_sagas_test.js index 2eb7939..38bcb06 100644 --- a/patterns/update_sagas_test.js +++ b/patterns/update_sagas_test.js @@ -1,3 +1,12 @@ +import * as sagas from '../sagas' +import * as types from '../types' +import * as actions from '../actions' +import firebase from '../firebase' +import { put, take, call, fork, cancel, flush } from 'redux-saga/effects' + +import { cloneableGenerator } from 'redux-saga/utils' +import { metaTypes } from '../types' + test(`watchUpdateRequested ${metaTypes.userContacts}`, () => { const generator = sagas.watchUpdateRequested() const updates = { updates: { a: '1', b: '2' } } diff --git a/sagas.js b/sagas.js index fc5c145..7f5744d 100644 --- a/sagas.js +++ b/sagas.js @@ -1,19 +1,9 @@ import * as types from './types' import { metaTypes, eventTypes } from './types' +import * as actions from './actions' import firebase from './firebase' import { eventChannel, buffers } from 'redux-saga' -import * as FirebaseActions from './actions' -import { - all, - put, - takeEvery, - take, - call, - fork, - cancel, - flush, - cancelled, -} from 'redux-saga/effects' +import { put, take, call, fork, cancel, flush } from 'redux-saga/effects' export function* watchUpdateRequested() { while (true) { @@ -63,9 +53,9 @@ export function* updateItems(updates, metaType) { try { const ref = firebase.database().ref() yield call([ref, ref.update], updates) - yield put(FirebaseActions.firebaseUpdateFulfilled(metaType)) + yield put(actions.firebaseUpdateFulfilled(metaType)) } catch (error) { - yield put(FirebaseActions.firebaseUpdateRejected(error, metaType)) + yield put(actions.firebaseUpdateRejected(error, metaType)) } } @@ -73,9 +63,9 @@ export function* removeItem(path, metaType) { try { const ref = firebase.database().ref(path) yield call([ref, ref.remove]) - yield put(FirebaseActions.firebaseRemoveFulfilled(metaType)) + yield put(actions.firebaseRemoveFulfilled(metaType)) } catch (error) { - yield put(FirebaseActions.firebaseRemoveRejected(error, metaType)) + yield put(actions.firebaseRemoveRejected(error, metaType)) } } @@ -116,9 +106,9 @@ export function* getDataAndListenToChannel(ref, metaType) { yield flush(chan) const val = snap.val() const value = val ? val : {} - yield put(FirebaseActions.firebaseListenFulfilled(value, metaType)) + yield put(actions.firebaseListenFulfilled(value, metaType)) } catch (error) { - yield put(FirebaseActions.firebaseListenRejected(error, metaType)) + yield put(actions.firebaseListenRejected(error, metaType)) } while (true) { const data = yield take(chan) @@ -132,19 +122,11 @@ export function* getDataAndListenToChannel(ref, metaType) { export function getUpdateAction(data, metaType) { switch (data.eventType) { case eventTypes.CHILD_ADDED: - return FirebaseActions.firebaseListenChildAdded( - data.key, - data.value, - metaType - ) + return actions.firebaseListenChildAdded(data.key, data.value, metaType) case eventTypes.CHILD_CHANGED: - return FirebaseActions.firebaseListenChildChanged( - data.key, - data.value, - metaType - ) + return actions.firebaseListenChildChanged(data.key, data.value, metaType) case eventTypes.CHILD_REMOVED: - return FirebaseActions.firebaseListenChildRemoved(data.key, metaType) + return actions.firebaseListenChildRemoved(data.key, metaType) } } @@ -173,10 +155,7 @@ export function* watchListener(metaType) { ) { yield cancel(task) yield put( - FirebaseActions.firebaseListenRemoved( - !!action.payload.clearItems, - metaType - ) + actions.firebaseListenRemoved(!!action.payload.clearItems, metaType) ) if (action.type === types.firebase.FIREBASE_LISTEN_REQUESTED) {