import { module, test } from 'qunit';
import Ember from 'ember';
import sinon from 'sinon';
import ExpiringMixin from 'web-client/models/core/mixins/instance/expiring';
import LoadingMixin from 'web-client/models/core/mixins/instance/loading';

const { Object: EmberObject } = Ember;

module('ExpiringMixin', {
  setup() {
    this.__clock = sinon.useFakeTimers();
  },

  __createResource(expiration, includeLoading) {
    let apiLoadPromise = this.__apiLoadPromise = $.Deferred();

    let mixin = EmberObject.extend(
      ExpiringMixin,
      includeLoading ? LoadingMixin : {},
      {
        expiration: expiration,
        apiLoad: function () {
          return apiLoadPromise;
        }
      });

    return mixin.create({id: 1});
  },

  teardown() {
    this.__clock.restore();
  }
});

test('model is never expired if expiration is not set', function (assert) {
  let resource = this.__createResource();
  assert.equal(resource.get('isExpired'), false);
  this.__clock.tick(10000000);
  assert.equal(resource.get('isExpired'), false);
});

test('resource is considered expired before it is loaded if past expiration time', function (assert) {
  let resource = this.__createResource(500, true);
  assert.equal(resource.get('isExpired'), false);
  resource.load();
  assert.equal(resource.get('isLoading'), true);
  assert.equal(resource.get('isLoaded'), false);
  assert.equal(resource.get('isExpired'), false);
  this.__clock.tick(501);
  assert.equal(resource.get('isExpired'), true);
});

test('resource is not expired until expiration time has passed after loading', function (assert) {
  let resource = this.__createResource(500, true);
  resource.load();
  this.__apiLoadPromise.resolve();
  assert.equal(resource.get('isLoaded'), true);
  assert.equal(resource.get('isExpired'), false);
  this.__clock.tick(501);
  assert.equal(resource.get('isExpired'), true);
});

test('resource is unexpired if loading finishes after expiring until expiration time again', function (assert) {
  let resource = this.__createResource(10, true);
  resource.load();
  this.__clock.tick(11);
  assert.equal(resource.get('isExpired'), true);
  this.__apiLoadPromise.resolve();
  assert.equal(resource.get('isExpired'), false);
  this.__clock.tick(11);
  assert.equal(resource.get('isExpired'), true);
});
