<!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-lite.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">

<script>void(0);</script>

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