@store-sync/redux-middleware
Version:
Redux middleware that syncs state
93 lines (77 loc) • 2.27 kB
text/typescript
import { createStore, applyMiddleware } from 'redux'
import Transport, {
StoreSyncMessage,
MessageListener,
} from '@store-sync/transport'
import StoreSync from './'
import Differ from '@store-sync/differ'
describe('storeSync', () => {
const alwaysTheDiff = [1, 2, 3]
class TestTransport implements Transport {
messages: StoreSyncMessage[] = []
listeners: MessageListener[] = []
send = jest.fn((msg: StoreSyncMessage) => {
this.messages.push(msg)
})
addMessageListener(listener: MessageListener) {
this.listeners.push(listener)
}
// receiveChange simulates a message coming through out
// actual transport. Used only for testing here
receiveChange(msg: StoreSyncMessage) {
this.listeners.forEach(listener => {
listener(msg)
})
}
}
class TestDiffer implements Differ<any[]> {
diff(a: [], b: []): any[] {
return alwaysTheDiff // for testing purposes, we always return the same diff
}
apply(a: [], patch: []) {
return [...a, ...patch]
}
}
const transport = new TestTransport()
const differ = new TestDiffer()
const storeSync = StoreSync({ transport, differ })
const theOneActionWeCareAbout = 'HELLO_WORLD'
const reducer = (
state: number[] = [],
action: { type: string; payload: number }
) => {
switch (action.type) {
case theOneActionWeCareAbout:
return [...state, action.payload]
}
return state
}
it('sends diffs', () => {
const store = createStore(reducer, [], applyMiddleware(storeSync))
store.dispatch({
type: theOneActionWeCareAbout,
payload: 1,
})
expect(store.getState()).toStrictEqual([1])
expect(transport.send).toHaveBeenCalledWith({
diff: alwaysTheDiff,
datetime: expect.any(Number),
})
})
it('applies diffs it receives', () => {
const mockReducer = jest.fn(reducer)
createStore(mockReducer, [], applyMiddleware(storeSync))
transport.receiveChange({
datetime: Date.now(),
diff: alwaysTheDiff,
})
expect(mockReducer).toHaveBeenLastCalledWith([], {
type: 'STORE_SYNC_UPDATE',
payload: alwaysTheDiff,
meta: {
datetime: expect.any(Number),
},
})
})
})