import { module, test } from 'qunit';
import BeforeUnloadGuard from 'web-client/utilities/video-uploader/before-unload-guard';
import RSVP from 'rsvp';
import run from 'ember-runloop';

module('Unit | Utils | before-unload-guard', {
  beforeEach() {
    this.win = new FakeWindow();
    this.beforeUnloadGuard = new BeforeUnloadGuard(this.win);
  }
});

test('it warns the user when a tracked promise is pending', function(assert) {
  let done = assert.async();
  assert.expect(5);

  let resolve;
  let promise = new RSVP.Promise((r) => resolve = r);
  this.beforeUnloadGuard.trackPromise(promise);

  assert.equal(this.beforeUnloadGuard.hasPendingPromises, true, "has pending promises");

  let event = {};
  assert.equal(this.win.listeners['beforeunload'](event), true, "warns user beforeunload with return value");
  assert.equal(event.returnValue, true, "and sets the event returnValue property");

  resolve();

  run.next(() => {
    assert.equal(this.beforeUnloadGuard.hasPendingPromises, false, "does not have pending promises");
    assert.equal(this.win.listeners['beforeunload'](event), undefined, "does not warn user beforeunload");

    done();
  });
});

test('tears down the event listener', function(assert) {
  assert.ok(this.win.listeners['beforeunload'], "sets up a listener during construction");

  this.beforeUnloadGuard.teardown();

  assert.equal(this.win.listeners['beforeunload'], undefined, "removes event listener on teardown");
});

class FakeWindow {
  constructor() {
    this.listeners = {};
  }

  addEventListener(eventName, listener) {
    this.listeners[eventName] = listener;
  }

  removeEventListener(eventName, listener) {
    if (this.listeners[eventName] === listener) {
      delete this.listeners[eventName];
    }
  }
}
