/* globals Twitch */
import moduleForComponent from 'web-client/tests/helpers/module-for-component';
import { test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import Ember from 'ember';
import sinon from 'sinon';
import wait from 'ember-test-helpers/wait';
const { RSVP, run } = Ember;

let getExperimentValue;

moduleForComponent('in-experiment-group', {
  integration: true,

  beforeEach() {
    getExperimentValue = sinon.stub(Twitch.experiments, 'getExperimentValue');
    getExperimentValue.withArgs('CHANNEL_PAGE_REDESIGN').returns(RSVP.resolve('old'));
    getExperimentValue.withArgs('DETERMINATION').returns(RSVP.resolve('no'));
  },

  afterEach() {
    Twitch.experiments.getExperimentValue.restore();
  }
});

test('determines whether a user is in a given experiment group', function(assert) {
  getExperimentValue.withArgs('EXP1').returns(RSVP.resolve('yes'));
  getExperimentValue.withArgs('EXP2').returns(RSVP.resolve('no'));

  this.set('experiment', 'EXP1');
  this.set('group', 'yes');
  this.render(hbs`{{if (in-experiment-group experiment group) "enabled" "disabled"}}`);
  assert.equal(this.$().text(), "enabled", "is enabled for EXP1, yes");

  this.set('group', 'no');
  assert.equal(this.$().text(), "disabled", "is disabled for EXP1, no");

  this.set('experiment', 'EXP2');
  assert.equal(this.$().text(), "enabled", "is enabled for EXP2, no");

  this.set('group', 'yes');
  assert.equal(this.$().text(), "disabled", "is disabled for EXP2, yes");
});

test('defaults to the "yes" group', function(assert) {
  getExperimentValue.withArgs('EXP').returns(RSVP.resolve('yes'));

  this.render(hbs`{{if (in-experiment-group 'EXP') "enabled" "disabled"}}`);
  assert.equal(this.$().text(), "enabled", "is enabled for EXP1, yes");
});

test('returns false when there is no experiment', function(assert) {
  getExperimentValue.withArgs('NOT_THERE').returns(RSVP.resolve(undefined));

  this.render(hbs`{{if (in-experiment-group 'NOT_THERE') "enabled" "disabled"}}`);
  assert.equal(this.$().text(), "disabled", "is disabled for missing experiment");
});

test('determines whether a value is in a comma-separated list', function(assert) {
  getExperimentValue.withArgs('EXP').returns(RSVP.resolve('one,two'));

  this.render(hbs`{{if (in-experiment-group 'EXP' 'one') "enabled" "disabled"}}`);
  assert.equal(this.$().text(), "enabled", "is enabled when there is a matching value");

  this.render(hbs`{{if (in-experiment-group 'EXP' 'not-there') "enabled" "disabled"}}`);
  assert.equal(this.$().text(), "disabled", "is disabled when there is no matching value");
});

test('does not error when destroyed with pending promise', function(assert) {
  assert.expect(0);

  let delayedResponse = new RSVP.Promise((resolve) => run.next(resolve));
  getExperimentValue.withArgs('EXP').returns(delayedResponse);

  this.render(hbs`{{in-experiment-group 'EXP' 'yes'}}`);
  this.clearRender();
});

test('recomputes value after experiment value resolves', function(assert) {
  assert.expect(2);

  let delayedResponse = new RSVP.Promise(function(resolve) {
    run.next(() => resolve('yes'));
  });

  getExperimentValue.withArgs('EXP').returns(delayedResponse);

  this.render(hbs`{{if (in-experiment-group 'EXP') "enabled" "disabled"}}`);

  assert.equal(this.$().text(), "disabled", "is disabled while promise is pending");

  return wait().then(() => {
    assert.equal(this.$().text(), "enabled", "is enabled when promise is resolved");
  });
});
