import wait from 'ember-test-helpers/wait';
import { test } from 'ember-qunit';

import moduleForIntegration from 'web-client/tests/helpers/module-for-integration';
import { stubLogin } from 'web-client/tests/helpers/stub-login';
import { UnauthenticatedError } from 'web-client/utilities/error';
import { JTV_USER_PICTURES_404_USER_70X70_URL } from 'web-client/utilities/urls/static-cdn';

moduleForIntegration('service:session', 'Integration | Service | Session');

test('#getCurrentUser rejects when not logged in', function(assert) {
  assert.expect(1);

  let service = this.subject();
  service.getCurrentUser().catch(error => {
    assert.ok(error instanceof UnauthenticatedError, 'rejects with unauthenticated error');
  });

  return wait();
});

test('#getCurrentUser resolves with userData when logged in', function(assert) {
  assert.expect(1);
  let username = 'twitch';

  stubLogin({ login: username });

  let service = this.subject();
  service.getCurrentUser().then(userData => {
    assert.equal(userData.name, username, 'resolves with userData');
  });

  return wait();
});

test('#initializeSession sets state when not logged in', function(assert) {
  assert.expect(6);

  let service = this.subject();

  assert.equal(service.isAuthenticated, null, 'isAuthenticated starts null');
  assert.equal(service.userData, null, 'userData starts null');
  assert.equal(service.userModel, null, 'userModel starts null');

  service.initializeSession().then(() => {
    assert.equal(service.isAuthenticated, false, 'isAuthenticated set');
    assert.equal(service.userData, null, 'userData still null');
    assert.equal(service.userModel, null, 'userModel still null');
  });

  return wait();
});

test('#initializeSession sets state when logged in', function(assert) {
  assert.expect(7);
  let username = 'twitch';

  stubLogin({ login: username, logo: null});

  let service = this.subject();

  assert.equal(service.isAuthenticated, null, 'isAuthenticated starts null');
  assert.equal(service.userData, null, 'userData starts null');
  assert.equal(service.userModel, null, 'userModel starts null');

  service.initializeSession().then(() => {
    assert.equal(service.isAuthenticated, true, 'isAuthenticated set');
    assert.equal(service.userData.name, username, 'userData set');
    assert.equal(service.get('userLogo'), JTV_USER_PICTURES_404_USER_70X70_URL, 'userLogo is set to a default');
    assert.equal(service.userModel.get('displayName'), username, 'userModel set with data');
  });

  return wait();
});

test('#userLogo is computed at expected times', function(assert) {
  assert.expect(3);
  let username = 'twitch';

  stubLogin({ login: username, logo: null});

  let service = this.subject();

  service.initializeSession().then(() => {
    assert.equal(service.get('userLogo'), JTV_USER_PICTURES_404_USER_70X70_URL, 'userLogo starts with default');
    let user = service.userModel;
    user.set('logo', 'hello');
    assert.equal(service.userModel.get('logo'), 'hello', 'userModel.logo is correctly updated');
    assert.equal(service.get('userLogo'), 'hello', 'userLogo is properly updated when userModel.logo is updated');
  });

  return wait();
});
