<!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;
    var sandbox;

    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 sandbox.stub(element.$.restAPI, 'addAccountEmail',
          function() { return Promise.resolve({status: statusCode}); });
    }

    setup(function(done) {
      sandbox = sinon.sandbox.create();
      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',
        email_format: 'HTML_PLAINTEXT',

        my: [
          {url: '/first/url', name: 'first name', target: '_blank'},
          {url: '/second/url', name: 'second name', target: '_blank'},
        ],
        change_table: [],
      };
      diffPreferences = {
        context: 10,
        tab_size: 8,
        font_size: 12,
        line_length: 100,
        cursor_blink_rate: 0,
        line_wrapping: false,
        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([]); },
      });
      element = fixture('basic');

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

    teardown(function() {
      sandbox.restore();
    });

    test('calls the title-change event', function() {
      var titleChangedStub = sandbox.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('Email format', 'preferences')
          .firstElementChild.bindValue, preferences.email_format);
      assert.equal(valueOf('Diff view', 'preferences')
          .firstElementChild.bindValue, preferences.diff_view);
      assert.equal(valueOf('Expand inline diffs', 'preferences')
          .firstElementChild.checked, false);

      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';

      var expandInlineDiffs =
          valueOf('Expand inline diffs', 'preferences').firstElementChild;
      diffSelect.fire('change');

      MockInteractions.tap(expandInlineDiffs);

      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);
          assert.equal(prefs.expand_inline_diffs, true);
          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('Diff width', 'diffPreferences')
          .firstElementChild.bindValue, diffPreferences.line_length);
      assert.equal(valueOf('Tab width', 'diffPreferences')
          .firstElementChild.bindValue, diffPreferences.tab_size);
      assert.equal(valueOf('Font size', 'diffPreferences')
          .firstElementChild.bindValue, diffPreferences.font_size);
      assert.equal(valueOf('Show tabs', 'diffPreferences')
          .firstElementChild.checked, diffPreferences.show_tabs);
      assert.equal(valueOf('Show trailing whitespace', 'diffPreferences')
          .firstElementChild.checked, diffPreferences.show_whitespace_errors);
      assert.equal(valueOf('Fit to screen', 'diffPreferences')
          .firstElementChild.checked, diffPreferences.line_wrapping);

      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('columns input is hidden with fit to scsreen is selected', function() {
      assert.isFalse(element.$.columnsPref.hidden);

      MockInteractions.tap(element.$.lineWrapping);
      assert.isTrue(element.$.columnsPref.hidden);

      MockInteractions.tap(element.$.lineWrapping);
      assert.isFalse(element.$.columnsPref.hidden);
    });

    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();
      });
    });

    test('emails are loaded without emailToken', function() {
      sandbox.stub(element.$.emailEditor, 'loadData');
      element.params = {};
      element.attached();
      assert.isTrue(element.$.emailEditor.loadData.calledOnce);
    });

    suite('when email verification token is provided', function() {
      var resolveConfirm;

      setup(function() {
        sandbox.stub(element.$.emailEditor, 'loadData');
        sandbox.stub(element.$.restAPI, 'confirmEmail', function() {
          return new Promise(function(resolve) { resolveConfirm = resolve; });
        });
        element.params = {emailToken: 'foo'};
        element.attached();
      });

      test('it is used to confirm email via rest API', function() {
        assert.isTrue(element.$.restAPI.confirmEmail.calledOnce);
        assert.isTrue(element.$.restAPI.confirmEmail.calledWith('foo'));
      });

      test('emails are not loaded initially', function() {
        assert.isFalse(element.$.emailEditor.loadData.called);
      });

      test('user emails are loaded after email confirmed', function(done) {
        element._loadingPromise.then(function() {
          assert.isTrue(element.$.emailEditor.loadData.calledOnce);
          done();
        });
        resolveConfirm();
      });

      test('show-alert is fired when email is confirmed', function(done) {
        sandbox.spy(element, 'fire');
        element._loadingPromise.then(function() {
          assert.isTrue(
              element.fire.calledWith('show-alert', {message: 'bar'}));
          done();
        });
        resolveConfirm('bar');
      });

    });
  });
</script>
