<!DOCTYPE html>
<!--
Copyright (C) 2016 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-settings-view</title>

<script src="../../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>

<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="gr-settings-view.html">

<test-fixture id="basic">
  <template>
    <gr-settings-view></gr-settings-view>
  </template>
</test-fixture>

<test-fixture id="blank">
  <template>
    <div></div>
  </template>
</test-fixture>

<script>
  suite('gr-settings-view tests', function() {
    var element;
    var account;
    var preferences;
    var diffPreferences;
    var config;

    function valueOf(title, fieldsetid) {
      var sections = element.$[fieldsetid].querySelectorAll('section');
      var titleEl;
      for (var i = 0; i < sections.length; i++) {
        titleEl = sections[i].querySelector('.title');
        if (titleEl.textContent === title) {
          return sections[i].querySelector('.value');
        }
      }
    }

    // Because deepEqual isn't behaving in Safari.
    function assertMenusEqual(actual, expected) {
      assert.equal(actual.length, expected.length);
      for (var i = 0; i < actual.length; i++) {
        assert.equal(actual[i].name, expected[i].name);
        assert.equal(actual[i].url, expected[i].url);
      }
    }

    function stubAddAccountEmail(statusCode) {
      return sinon.stub(element.$.restAPI, 'addAccountEmail',
          function() { return Promise.resolve({status: statusCode}); });
    }

    setup(function(done) {
      account = {
        _account_id: 123,
        name: 'user name',
        email: 'user@email',
        username: 'user username',
        registered: '2000-01-01 00:00:00.000000000',
      };
      preferences = {
        changes_per_page: 25,
        date_format: 'UK',
        time_format: 'HHMM_12',
        diff_view: 'UNIFIED_DIFF',
        email_strategy: 'ENABLED',

        my: [
          {url: '/first/url', name: 'first name', target: '_blank'},
          {url: '/second/url', name: 'second name', target: '_blank'},
        ],
      };
      diffPreferences = {
        context: 10,
        tab_size: 8,
        line_length: 100,
        cursor_blink_rate: 0,
        intraline_difference: true,
        show_line_endings: true,
        show_tabs: true,
        show_whitespace_errors: true,
        syntax_highlighting: true,
        auto_hide_diff_table_header: true,
        theme: 'DEFAULT',
        ignore_whitespace: 'IGNORE_NONE'
      };
      config = {auth: {editable_account_fields: []}};

      stub('gr-rest-api-interface', {
        getLoggedIn: function() { return Promise.resolve(true); },
        getAccount: function() { return Promise.resolve(account); },
        getPreferences: function() { return Promise.resolve(preferences); },
        getDiffPreferences: function() {
          return Promise.resolve(diffPreferences);
        },
        getWatchedProjects: function() {
          return Promise.resolve([]);
        },
        getAccountEmails: function() { return Promise.resolve(); },
        getConfig: function() { return Promise.resolve(config); },
        getAccountGroups: function() { return Promise.resolve([]); },
        getAccountHttpPassword: function() { return Promise.resolve(''); },
      });
      element = fixture('basic');

      // Allow the element to render.
      element._loadingPromise.then(done);
    });

    test('calls the title-change event', function() {
      var titleChangedStub = sinon.stub();

      // Create a new view.
      var newElement = document.createElement('gr-settings-view');
      newElement.addEventListener('title-change', titleChangedStub);

      // Attach it to the fixture.
      var blank = fixture('blank');
      blank.appendChild(newElement);

      Polymer.dom.flush();

      assert.isTrue(titleChangedStub.called);
      assert.equal(titleChangedStub.getCall(0).args[0].detail.title,
          'Settings');
    });

    test('user preferences', function(done) {
      // Rendered with the expected preferences selected.
      assert.equal(valueOf('Changes Per Page', 'preferences')
          .firstElementChild.bindValue, preferences.changes_per_page);
      assert.equal(valueOf('Date/Time Format', 'preferences')
          .firstElementChild.bindValue, preferences.date_format);
      assert.equal(valueOf('Date/Time Format', 'preferences')
          .lastElementChild.bindValue, preferences.time_format);
      assert.equal(valueOf('Email Notifications', 'preferences')
          .firstElementChild.bindValue, preferences.email_strategy);
      assert.equal(valueOf('Diff View', 'preferences')
          .firstElementChild.bindValue, preferences.diff_view);

      assert.isFalse(element._prefsChanged);
      assert.isFalse(element._menuChanged);

      // Change the diff view element.
      var diffSelect = valueOf('Diff View', 'preferences').firstElementChild;
      diffSelect.bindValue = 'SIDE_BY_SIDE';
      diffSelect.fire('change');

      assert.isTrue(element._prefsChanged);
      assert.isFalse(element._menuChanged);

      stub('gr-rest-api-interface', {
        savePreferences: function(prefs) {
          assert.equal(prefs.diff_view, 'SIDE_BY_SIDE');
          assertMenusEqual(prefs.my, preferences.my);
          return Promise.resolve();
        }
      });

      // Save the change.
      element._handleSavePreferences().then(function() {
        assert.isFalse(element._prefsChanged);
        assert.isFalse(element._menuChanged);
        done();
      });
    });

    test('diff preferences', function(done) {
      // Rendered with the expected preferences selected.
      assert.equal(valueOf('Context', 'diffPreferences')
          .firstElementChild.bindValue, diffPreferences.context);
      assert.equal(valueOf('Columns', 'diffPreferences')
          .firstElementChild.bindValue, diffPreferences.line_length);
      assert.equal(valueOf('Tab Width', 'diffPreferences')
          .firstElementChild.bindValue, diffPreferences.tab_size);
      assert.equal(valueOf('Show Tabs', 'diffPreferences')
          .firstElementChild.checked, diffPreferences.show_tabs);

      assert.isFalse(element._diffPrefsChanged);

      var showTabsCheckbox = valueOf('Show Tabs', 'diffPreferences')
          .firstElementChild;
      showTabsCheckbox.checked = false;
      element._handleShowTabsChanged();

      assert.isTrue(element._diffPrefsChanged);

      stub('gr-rest-api-interface', {
        saveDiffPreferences: function(prefs) {
          assert.equal(prefs.show_tabs, false);
          return Promise.resolve();
        }
      });

      // Save the change.
      element._handleSaveDiffPreferences().then(function() {
        assert.isFalse(element._diffPrefsChanged);
        done();
      });
    });

    test('menu', function(done) {
      assert.isFalse(element._menuChanged);
      assert.isFalse(element._prefsChanged);

      assertMenusEqual(element._localMenu, preferences.my);

      var menu = element.$.menu.firstElementChild;
      var tableRows = Polymer.dom(menu.root).querySelectorAll('tbody tr');
      assert.equal(tableRows.length, preferences.my.length);

      // Add a menu item:
      element.splice('_localMenu', 1, 0, {name: 'foo', url: 'bar', target: ''});
      Polymer.dom.flush();

      tableRows = Polymer.dom(menu.root).querySelectorAll('tbody tr');
      assert.equal(tableRows.length, preferences.my.length + 1);

      assert.isTrue(element._menuChanged);
      assert.isFalse(element._prefsChanged);

      stub('gr-rest-api-interface', {
        savePreferences: function(prefs) {
          assertMenusEqual(prefs.my, element._localMenu);
          return Promise.resolve();
        }
      });

      element._handleSaveMenu().then(function() {
        assert.isFalse(element._menuChanged);
        assert.isFalse(element._prefsChanged);
        assertMenusEqual(element.prefs.my, element._localMenu);
        done();
      });
    });

    test('add email validation', function() {
      assert.isFalse(element._isNewEmailValid('invalid email'));
      assert.isTrue(element._isNewEmailValid('vaguely@valid.email'));

      assert.isFalse(
          element._computeAddEmailButtonEnabled('invalid email'), true);
      assert.isFalse(
          element._computeAddEmailButtonEnabled('vaguely@valid.email', true));
      assert.isTrue(
          element._computeAddEmailButtonEnabled('vaguely@valid.email', false));
    });

    test('add email does not save invalid', function() {
      var addEmailStub = stubAddAccountEmail(201);

      assert.isFalse(element._addingEmail);
      assert.isNotOk(element._lastSentVerificationEmail);
      element._newEmail = 'invalid email';

      element._handleAddEmailButton();

      assert.isFalse(element._addingEmail);
      assert.isFalse(addEmailStub.called);
      assert.isNotOk(element._lastSentVerificationEmail);

      assert.isFalse(addEmailStub.called);
    });

    test('add email does save valid', function(done) {
      var addEmailStub = stubAddAccountEmail(201);

      assert.isFalse(element._addingEmail);
      assert.isNotOk(element._lastSentVerificationEmail);
      element._newEmail = 'valid@email.com';

      element._handleAddEmailButton();

      assert.isTrue(element._addingEmail);
      assert.isTrue(addEmailStub.called);

      assert.isTrue(addEmailStub.called);
      addEmailStub.lastCall.returnValue.then(function() {
        assert.isOk(element._lastSentVerificationEmail);
        done();
      });
    });

    test('add email does not set last-email if error', function(done) {
      var addEmailStub = stubAddAccountEmail(500);

      assert.isNotOk(element._lastSentVerificationEmail);
      element._newEmail = 'valid@email.com';

      element._handleAddEmailButton();

      assert.isTrue(addEmailStub.called);
      addEmailStub.lastCall.returnValue.then(function() {
        assert.isNotOk(element._lastSentVerificationEmail);
        done();
      });
    });
  });
</script>
