import { expect } from 'chai'; import { initialState, crud } from 'reducers/crud'; import { docCreated, docCreateResponded, docRead, docReadResponded, docUpdated, docUpdateResponded, docDeleted, docDeleteResponded } from 'actions/crud'; describe('CRUD reducer', () => { it('should return the initial state by default', () => { // eslint-disable-next-line no-undefined expect(crud(undefined, null)).to.equal(initialState); }); describe('DOC_CREATED', () => { const route = 'employees'; const pendingId = 'foo19123afvj'; const action = docCreated(route, pendingId, { name: 'John Doe', email: 'john.doe@mubaloo.com' }); it('should create an optimistic update (pending) in state', () => { const state = {}; const result = crud(state, action); expect(result).to.have.property(route); expect(result[route]).to.be.an('object'); expect(result[route]).to.have.property('items'); expect(result[route].items).to.be.an('array').of.length(1); expect(result[route].items[0]).to.be.an('object'); expect(result[route].items[0]).to.deep.equal({ id: pendingId, pending: true, name: 'John Doe', email: 'john.doe@mubaloo.com' }); }); it('should not do anything if the state is loading', () => { const state = { [route]: { loading: true, items: [] } }; const result = crud(state, action); expect(result[route].items).to.have.length(0); }); }); describe('DOC_CREATE_RESPONDED', () => { const route = 'employees'; const pendingId = 'foo19123afvj'; const state = { [route]: { items: [ { id: pendingId, pending: true, name: 'John Doe', email: 'john.doe@mubaloo.com' } ] } }; const actualId = 'a0b444511123'; const response = { data: { id: actualId, name: 'John Doe', email: 'john.doe@mubaloo.com' } }; const actionSuccess = docCreateResponded(route, pendingId, null, response); it('should mark an optimistically created document as successful, if the response was success', () => { const result = crud(state, actionSuccess); expect(result[route].items).to.have.length(1); expect(result[route].items[0]).to.have.property('id', actualId); expect(result[route].items[0]).to.have.property('pending', false); }); it('should remove the pending item and set an error status if an error occurred', () => { const error = new Error('something bad happened'); const action = docCreateResponded(route, pendingId, error, null); const result = crud(state, action); expect(result[route].items).to.have.length(0); expect(result[route]).to.have.property('error', true); }); }); describe('DOC_READ', () => { it('should set the route to loading', () => { const state = {}; const route = 'employees'; const action = docRead(route); const result = crud(state, action); expect(result).to.have.property(route); expect(result[route]).to.be.an('object'); expect(result[route]).to.have.property('loading', true); expect(result[route]).to.have.property('items'); expect(result[route].items).to.be.an('array').of.length(0); }); }); describe('DOC_READ_RESPONDED', () => { const route = 'employees'; const state = { [route]: { loading: true, items: [] } }; const actualId = 'a0b444511123'; const response = { data: { [route]: [ { id: actualId, name: 'John Doe', email: 'john.doe@mubaloo.com' } ] } }; const actionSuccess = docReadResponded(route, null, response); const resultSuccess = crud(state, actionSuccess); it('should add the response to state', () => { expect(resultSuccess[route].items).to.have.length(1); expect(resultSuccess[route].items[0]).to.have.property('id', actualId); expect(resultSuccess[route].items[0]).to.have.property('name', 'John Doe'); expect(resultSuccess[route].items[0]).to.have.property('email', 'john.doe@mubaloo.com'); }); it('should set loading to false', () => { expect(resultSuccess[route].loading).to.equal(false); }); it('should set an error status if an error occurred', () => { const error = new Error('something bad happened'); const action = docReadResponded(route, error, null); const resultError = crud(state, action); expect(resultError[route].items).to.have.length(0); expect(resultError[route].error).to.equal(true); expect(resultError[route].loading).to.equal(false); }); }); describe('DOC_UPDATED', () => { const route = 'employees'; const actualId = 'a0b444511123'; const action = docUpdated(route, actualId, { name: 'John Doe', email: 'john.doe@mubaloo.com' }); it('should optimistically update the item (pending) in state', () => { const state = { [route]: { items: [ { id: actualId, name: 'Jack', email: 'jack@mubaloo.com' } ] } }; const result = crud(state, action); expect(result[route].items).to.have.length(1); expect(result[route].items[0]).to.have.property('pending', true); expect(result[route].items[0]).to.deep.equal({ id: actualId, pending: true, name: 'John Doe', email: 'john.doe@mubaloo.com' }); }); it('should not do anything if the state is loading', () => { const state = { [route]: { loading: true, items: [] } }; const result = crud(state, action); expect(result[route].items).to.have.length(0); }); }); describe('DOC_UPDATE_RESPONDED', () => { const route = 'employees'; const actualId = 'a0b444511123'; const state = { [route]: { items: [ { id: actualId, pending: true, name: 'John Doe', email: 'john.doe@mubaloo.com' } ] } }; const response = { data: { ok: true } }; const actionSuccess = docUpdateResponded(route, actualId, null, response); it('should mark an optimistically updated document as successful, if the response was success', () => { const result = crud(state, actionSuccess); expect(result[route].items).to.have.length(1); expect(result[route].items[0]).to.have.property('pending', false); }); it('should set an error status if an error occurred', () => { const error = new Error('something bad happened'); const action = docUpdateResponded(route, actualId, error, null); const result = crud(state, action); expect(result[route].items).to.have.length(1); expect(result[route]).to.have.property('error', true); expect(result[route].items[0]).to.have.property('pending', false); }); }); describe('DOC_DELETED', () => { const route = 'employees'; const actualId = 'a0b444511123'; it('should mark the document as pending', () => { const state = { [route]: { items: [ { id: actualId, pending: false, name: 'John Doe', email: 'john.doe@mubaloo.com' } ] } }; const action = docDeleted(route, actualId); const result = crud(state, action); expect(result[route].items).to.have.length(1); expect(result[route].items[0]).to.have.property('pending', true); }); }); describe('DOC_DELETE_RESPONDED', () => { const route = 'employees'; const actualId = 'a0b444511123'; const state = { [route]: { items: [ { id: actualId, pending: true, name: 'John Doe', email: 'john.doe@mubaloo.com' } ] } }; it('should remove the document if the response was success', () => { const response = { data: { ok: true } }; const action = docDeleteResponded(route, actualId, null, response); const result = crud(state, action); expect(result[route].items).to.have.length(0); }); it('should set an error status if an error occurred', () => { const error = new Error('something bad happened'); const action = docDeleteResponded(route, actualId, error, null); const result = crud(state, action); expect(result[route]).to.have.property('error', true); expect(result[route].items).to.have.length(1); expect(result[route].items[0]).to.have.property('pending', false); }); }); });