"use strict";

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

var _immutable = require("immutable");

var _TimerService = _interopRequireDefault(require("../TimerService"));

describe('TimerService', function () {
  var timer;
  var clock;
  var updateTimeRemainingStub = sinon.stub();
  var submitQuizStub = sinon.stub();
  var alertStub = sinon.stub();
  beforeEach(function () {
    clock = sinon.useFakeTimers();

    var getTimeRemaining = function getTimeRemaining(cb) {
      cb({
        timerRunning: true,
        timeLeftInSeconds: 100
      });
    };

    var getTimerData = function getTimerData() {
      return (0, _immutable.Map)({
        timerRunning: true,
        timeLeftInSeconds: 100
      });
    };

    timer = new _TimerService.default(getTimeRemaining, updateTimeRemainingStub, getTimerData, submitQuizStub, alertStub);
  });
  afterEach(function () {
    clock.restore();
    updateTimeRemainingStub.resetHistory();
    submitQuizStub.resetHistory();
    alertStub.resetHistory();
  });
  it('performs the API call immediately upon starting', function () {
    expect(updateTimeRemainingStub.callCount).to.eq(0);
    timer.start();
    expect(updateTimeRemainingStub.callCount).to.eq(1);
  });
  it('does not allow restarting', function () {
    timer.start();
    timer.stop();
    expect(function () {
      return timer.start();
    }).to.throw(Error);
  });
  it('sets a clock interval upon starting', function () {
    timer.start();
    expect(timer._clockInterval).to.not.be.null();
  });
  it('updates the remaining time on the clock interval', function () {
    timer.start();
    clock.tick(1000);
    expect(updateTimeRemainingStub.callCount).to.eq(2);
    clock.tick(1000);
    expect(updateTimeRemainingStub.callCount).to.eq(3);
  });
  it('updates the remaining time on the API interval', function () {
    timer.start();
    clock.tick(9000);
    expect(updateTimeRemainingStub.callCount).to.eq(10);
    clock.tick(1000);
    expect(updateTimeRemainingStub.callCount).to.eq(12);
  });
  it('only starts the clock when the API says the timer is running', function () {
    timer._getTimerData = function () {
      return (0, _immutable.Map)({
        timerRunning: false,
        timeLeftInSeconds: 100
      });
    };

    timer.start();
    clock.tick(1000);
    expect(updateTimeRemainingStub.callCount).to.eq(1);
  });
  it('does not submit the quiz before the timer has run out', function () {
    timer._getTimerData = function () {
      return (0, _immutable.Map)({
        timeLeftInSeconds: 100
      });
    };

    timer.start();
    clock.tick(99);
    expect(submitQuizStub.called).to.be.false();
  });
  it('submits the quiz when the timer has run out', function () {
    var timeLeft = 1;

    timer._updateTimeRemaining = function (_ref) {
      var timeLeftInSeconds = _ref.timeLeftInSeconds;
      timeLeft = timeLeftInSeconds;
    };

    timer._getTimerData = function () {
      return (0, _immutable.Map)({
        timerRunning: true,
        timeLeftInSeconds: timeLeft
      });
    };

    timer._getTimeRemaining = function (cb) {
      cb({
        timerRunning: true,
        timeLeftInSeconds: 1
      });
    };

    timer.start();
    clock.tick(1000);
    expect(submitQuizStub.callCount).to.be.eq(1);
  });
  it('stops after submitting a quiz', function () {
    var timeLeft = 1;

    timer._updateTimeRemaining = function (_ref2) {
      var timeLeftInSeconds = _ref2.timeLeftInSeconds;
      timeLeft = timeLeftInSeconds;
    };

    timer._getTimerData = function () {
      return (0, _immutable.Map)({
        timerRunning: true,
        timeLeftInSeconds: timeLeft
      });
    };

    timer._getTimeRemaining = function (cb) {
      cb({
        timerRunning: true,
        timeLeftInSeconds: 1
      });
    };

    timer.start();
    expect(timer._apiInterval).to.not.be.null();
    clock.tick(2000);
    expect(timer._apiInterval).to.be.null();
    expect(submitQuizStub.callCount).to.eq(1);
  });
  it('does not submit the quiz if time remaining is null', function () {
    timer._getTimerData = function () {
      return (0, _immutable.Map)({
        timerRunning: false,
        timeLeftInSeconds: null
      });
    };

    timer._getTimeRemaining = function (cb) {
      cb({
        timerRunning: false,
        timeLeftInSeconds: null
      });
    };

    timer.start();
    clock.tick(2000);
    expect(submitQuizStub.called).to.be.false();
  });
  it('calls the alert only once after hitting the 30 second mark', function () {
    var timeLeft = 32;

    timer._updateTimeRemaining = function (_ref3) {
      var timeLeftInSeconds = _ref3.timeLeftInSeconds;
      timeLeft = timeLeftInSeconds;
    };

    timer._getTimerData = function () {
      return (0, _immutable.Map)({
        timerRunning: true,
        timeLeftInSeconds: timeLeft
      });
    };

    timer._getTimeRemaining = function (cb) {
      cb({
        timerRunning: true,
        timeLeftInSeconds: timeLeft
      });
    };

    timer.start();
    clock.tick(1000);
    expect(alertStub.callCount).to.eq(0);
    clock.tick(1000);
    expect(alertStub.callCount).to.eq(1);
    clock.tick(1000);
    expect(alertStub.callCount).to.eq(1);
    clock.tick(1000);
    expect(alertStub.callCount).to.eq(1);
    expect(alertStub.calledWith('You have less than 30 seconds remaining.')).to.be.true();
  });
});