-
-
Save rainstormza/92126ace17fd9f113098685bf97207c7 to your computer and use it in GitHub Desktop.
Example of making a channel in redux-saga with a firebase source and testing it with jest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { eventChannel } from 'redux-saga' | |
function firebaseChannel(firebase, { | |
eventType = 'value', | |
returnSnapshot = false, | |
} = {}) { | |
return eventChannel(emit => { | |
const subscription = firebase.on(eventType, snapshot => { | |
emit(returnSnapshot ? { snapshot } : { value: snapshot.val() }) | |
}) | |
return () => firebase.off(eventType, subscription) | |
}) | |
} | |
class FakeFirebase { | |
constructor() { | |
this.subs = [] | |
this.count = 0 | |
} | |
on(type, listener) { | |
this.subs.push({ | |
type, | |
listener, | |
id: this.count++, | |
}) | |
return this.count | |
} | |
off(type, id) { | |
this.subs = this.subs.filter(sub => sub.id !== id) | |
} | |
emit({ type: t, snapshot }) { | |
this.subs.forEach(({ type, listener }) => { | |
if (type === t) listener(snapshot) | |
}) | |
} | |
} | |
class FakeSnapshot { | |
val = jest.fn(() => 42) | |
} | |
describe('firebaseChannel', () => { | |
it('should subscribe to firebase, emit the values into the channel that firebase ' + | |
'emits, and unsubscribe when the channel is closed', async () => { | |
const firebase = new FakeFirebase() | |
const channel = firebaseChannel(firebase) | |
const taken = new Promise(resolve => channel.take(resolve)) | |
const snapshot = new FakeSnapshot() | |
firebase.emit({ type: 'value', snapshot }) | |
const value = await taken | |
expect(value).toEqual({ value: snapshot.val() }) | |
const spy = jest.spyOn(firebase, 'off') | |
channel.close() | |
expect(spy).toHaveBeenCalledWith('value', 1) | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment