"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

var _ThunkQueue = _interopRequireDefault(require("../ThunkQueue"));

describe('ThunkQueue', function () {
  var dispatch = function dispatch() {};

  var getState = function getState() {};

  describe('#wrapActionCreator', function () {
    it('returns a function', function () {
      var queue = new _ThunkQueue.default();
      expect(queue.wrapActionCreator(function () {})).to.be.a('function');
    });
    it('returns an action creator that wraps returned thunks', function () {
      var thunk = function thunk() {};

      var actionCreator = sinon.stub().returns(thunk);
      var queue = new _ThunkQueue.default();
      var wrapThunk = sinon.stub(queue, 'wrapThunk');
      var wrappedActionCreator = queue.wrapActionCreator(actionCreator);
      wrappedActionCreator('foo');
      expect(actionCreator).to.have.been.calledOnce();
      expect(actionCreator).to.have.been.calledWith('foo');
      expect(wrapThunk).to.have.been.calledOnce();
      expect(wrapThunk).to.have.been.calledWith(thunk);
    });
  });
  describe('#wrapThunk', function () {
    it('returns regular redux actions unmodified', function () {
      var queue = new _ThunkQueue.default();
      var action = {
        type: 'SOME_ACTION'
      };
      expect(queue.wrapThunk(action)).to.deep.equal(action);
    });
    it('returns a function',
    /*#__PURE__*/
    (0, _asyncToGenerator2.default)(
    /*#__PURE__*/
    _regenerator.default.mark(function _callee() {
      var queue;
      return _regenerator.default.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              queue = new _ThunkQueue.default();
              expect(queue.wrapThunk(function () {})).to.be.a('function');

            case 2:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    })));
    it('calls the given thunk immediately when empty',
    /*#__PURE__*/
    (0, _asyncToGenerator2.default)(
    /*#__PURE__*/
    _regenerator.default.mark(function _callee2() {
      var thunk, queue, wrappedThunk;
      return _regenerator.default.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              thunk = sinon.spy();
              queue = new _ThunkQueue.default();
              wrappedThunk = queue.wrapThunk(thunk);
              _context2.next = 5;
              return wrappedThunk(dispatch, getState);

            case 5:
              expect(thunk).to.have.been.calledOnce();
              expect(thunk).to.have.been.calledWith(dispatch, getState);

            case 7:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2);
    })));
    it('waits when there are thunks in the queue',
    /*#__PURE__*/
    (0, _asyncToGenerator2.default)(
    /*#__PURE__*/
    _regenerator.default.mark(function _callee3() {
      var thunks, queue, wrappedThunks, promises;
      return _regenerator.default.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              thunks = [sinon.stub().resolves(), sinon.stub().resolves()];
              queue = new _ThunkQueue.default();
              wrappedThunks = thunks.map(function (thunk) {
                return queue.wrapThunk(thunk);
              });
              promises = wrappedThunks.map(function (thunk) {
                return thunk(dispatch, getState);
              });
              _context3.next = 6;
              return promises[0];

            case 6:
              expect(thunks[0]).to.have.been.calledOnce();
              expect(thunks[0]).to.have.been.calledWith(dispatch, getState);
              expect(thunks[1]).not.to.have.been.called();
              _context3.next = 11;
              return promises[1];

            case 11:
              expect(thunks[0]).to.have.been.calledOnce();
              expect(thunks[1]).to.have.been.calledOnce();
              expect(thunks[1]).to.have.been.calledWith(dispatch, getState);

            case 14:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3);
    })));
    context('on error', function () {
      it('calls the given error handler',
      /*#__PURE__*/
      (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee4() {
        var error, thunk, errorHandler, queue, wrappedThunk;
        return _regenerator.default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                error = new Error('FAIL');
                thunk = sinon.stub().rejects(error);
                errorHandler = sinon.spy();
                queue = new _ThunkQueue.default(errorHandler);
                wrappedThunk = queue.wrapThunk(thunk);
                _context4.next = 7;
                return wrappedThunk(dispatch, getState);

              case 7:
                expect(errorHandler).to.have.been.calledOnce();
                expect(errorHandler).to.have.been.calledWith(error, dispatch, getState);

              case 9:
              case "end":
                return _context4.stop();
            }
          }
        }, _callee4);
      })));
      it('rejects if no error handler is given',
      /*#__PURE__*/
      (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee5() {
        var error, thunk, queue, wrappedThunk;
        return _regenerator.default.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                error = new Error('FAIL');
                thunk = sinon.stub().rejects(error);
                queue = new _ThunkQueue.default();
                wrappedThunk = queue.wrapThunk(thunk);
                _context5.next = 6;
                return expect(wrappedThunk(dispatch, getState)).to.be.rejectedWith(error);

              case 6:
              case "end":
                return _context5.stop();
            }
          }
        }, _callee5);
      })));
      it('rejects with the error thrown by the error handler',
      /*#__PURE__*/
      (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee6() {
        var thunk, error, errorHandler, queue, wrappedThunk;
        return _regenerator.default.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                thunk = sinon.stub().rejects();
                error = new Error('FAIL');
                errorHandler = sinon.stub().rejects(error);
                queue = new _ThunkQueue.default(errorHandler);
                wrappedThunk = queue.wrapThunk(thunk);
                _context6.next = 7;
                return expect(wrappedThunk(dispatch, getState)).to.be.rejectedWith(error);

              case 7:
              case "end":
                return _context6.stop();
            }
          }
        }, _callee6);
      })));
      it('cancels pending thunks',
      /*#__PURE__*/
      (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee7() {
        var queue, thunks, wrappedThunks, promises;
        return _regenerator.default.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                queue = new _ThunkQueue.default(function () {});
                thunks = [sinon.stub().rejects(), sinon.stub().resolves()];
                wrappedThunks = thunks.map(function (thunk) {
                  return queue.wrapThunk(thunk);
                });
                promises = wrappedThunks.map(function (thunk) {
                  return thunk(dispatch, getState);
                });
                _context7.next = 6;
                return Promise.all(promises);

              case 6:
                expect(thunks[0]).to.have.been.calledOnce();
                expect(thunks[1]).not.to.have.been.called();

              case 8:
              case "end":
                return _context7.stop();
            }
          }
        }, _callee7);
      })));
      it('resolves new thunks normally after handling an error',
      /*#__PURE__*/
      (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee8() {
        var queue, thunks, wrappedThunks;
        return _regenerator.default.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                queue = new _ThunkQueue.default(function () {});
                thunks = [sinon.stub().rejects(), sinon.stub().resolves()];
                wrappedThunks = thunks.map(function (thunk) {
                  return queue.wrapThunk(thunk);
                });
                _context8.next = 5;
                return wrappedThunks[0](dispatch, getState);

              case 5:
                _context8.next = 7;
                return wrappedThunks[1](dispatch, getState);

              case 7:
                expect(thunks[1]).to.have.been.calledOnce();
                expect(thunks[1]).to.have.been.calledWith(dispatch, getState);

              case 9:
              case "end":
                return _context8.stop();
            }
          }
        }, _callee8);
      })));
    });
  });
});