<!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-watched-projects-editor.html">

<test-fixture id="basic">
  <template>
    <gr-watched-projects-editor></gr-watched-projects-editor>
  </template>
</test-fixture>

<script>
  suite('gr-watched-projects-editor tests', function() {
    var element;

    setup(function(done) {
      var projects = [{
          project: 'project a',
          notify_submitted_changes: true,
          notify_abandoned_changes: true,
        }, {
          project: 'project b',
          filter: 'filter 1',
          notify_new_changes: true,
        }, {
          project: 'project b',
          filter: 'filter 2',
        }, {
          project: 'project c',
          notify_new_changes: true,
          notify_new_patch_sets: true,
          notify_all_comments: true,
        },
      ];

      stub('gr-rest-api-interface', {
        getSuggestedProjects: function(input) {
          if (input.indexOf('the') === 0) {
            return Promise.resolve({'the project': {
              id: 'the project',
              state: 'ACTIVE',
              web_links: [],
            }});
          } else {
            return Promise.resolve({});
          }
        },
        getWatchedProjects: function() {
          return Promise.resolve(projects);
        },
      });

      element = fixture('basic');

      element.loadData().then(function() { flush(done) });
    });

    test('renders', function() {
      var rows = element.$$('table').querySelectorAll('tbody tr');
      assert.equal(rows.length, 4);

      function getKeysOfRow(row) {
        var boxes = rows[row].querySelectorAll('input[checked]');
        return Array.prototype.map.call(boxes,
            function(e) { return e.getAttribute('data-key'); });
      }

      var checkedKeys = getKeysOfRow(0);
      assert.equal(checkedKeys.length, 2);
      assert.equal(checkedKeys[0], 'notify_submitted_changes');
      assert.equal(checkedKeys[1], 'notify_abandoned_changes');

      checkedKeys = getKeysOfRow(1);
      assert.equal(checkedKeys.length, 1);
      assert.equal(checkedKeys[0], 'notify_new_changes');

      checkedKeys = getKeysOfRow(2);
      assert.equal(checkedKeys.length, 0);

      checkedKeys = getKeysOfRow(3);
      assert.equal(checkedKeys.length, 3);
      assert.equal(checkedKeys[0], 'notify_new_changes');
      assert.equal(checkedKeys[1], 'notify_new_patch_sets');
      assert.equal(checkedKeys[2], 'notify_all_comments');
    });

    test('_getProjectSuggestions empty', function(done) {
      element._getProjectSuggestions('nonexistent').then(function(projects) {
        assert.equal(projects.length, 0);
        done();
      });
    });

    test('_getProjectSuggestions non-empty', function(done) {
      element._getProjectSuggestions('the project').then(function(projects) {
        assert.equal(projects.length, 1);
        assert.equal(projects[0].name, 'the project');
        done();
      });
    });

    test('_canAddProject', function() {
      assert.isFalse(element._canAddProject(null, null));
      assert.isFalse(element._canAddProject({}, null));

      // Can add a project that is not in the list.
      assert.isTrue(element._canAddProject({id: 'project d'}, null));
      assert.isTrue(element._canAddProject({id: 'project d'}, 'filter 3'));

      // Cannot add a project that is in the list with no filter.
      assert.isFalse(element._canAddProject({id: 'project a'}, null));

      // Can add a project that is in the list if the filter differs.
      assert.isTrue(element._canAddProject({id: 'project a'}, 'filter 4'));

      // Cannot add a project that is in the list with the same filter.
      assert.isFalse(element._canAddProject({id: 'project b'}, 'filter 1'));
      assert.isFalse(element._canAddProject({id: 'project b'}, 'filter 2'));

      // Can add a projec that is in the list using a new filter.
      assert.isTrue(element._canAddProject({id: 'project b'}, 'filter 3'));
    });

    test('_getNewProjectIndex', function() {
      // Projects are sorted in ASCII order.
      assert.equal(element._getNewProjectIndex('project A', 'filter'), 0);
      assert.equal(element._getNewProjectIndex('project a', 'filter'), 1);

      // Projects are sorted by filter when the names are equal
      assert.equal(element._getNewProjectIndex('project b', 'filter 0'), 1);
      assert.equal(element._getNewProjectIndex('project b', 'filter 1.5'), 2);
      assert.equal(element._getNewProjectIndex('project b', 'filter 3'), 3);

      // Projects with filters follow those without
      assert.equal(element._getNewProjectIndex('project c', 'filter'), 4);
    });

    test('_handleAddProject', function() {
      element.$.newProject.value = {id: 'project d'};
      element.$.newProject.setText('project d');
      element.$.newFilter.bindValue = '';

      element._handleAddProject();

      assert.equal(element._projects.length, 5);
      assert.equal(element._projects[4].project, 'project d');
      assert.isNotOk(element._projects[4].filter);
      assert.isTrue(element._projects[4]._is_local);
    });

    test('_handleAddProject with invalid inputs', function() {
      element.$.newProject.value = {id: 'project b'};
      element.$.newProject.setText('project b');
      element.$.newFilter.bindValue = 'filter 1';

      element._handleAddProject();

      assert.equal(element._projects.length, 4);
    });

    test('_handleRemoveProject', function() {
      assert.equal(element._projectsToRemove, 0);

      var button = element.$$('table tbody tr:nth-child(2) gr-button');
      MockInteractions.tap(button);

      var rows = element.$$('table tbody').querySelectorAll('tr');
      assert.equal(rows.length, 3);

      assert.equal(element._projectsToRemove.length, 1);
      assert.equal(element._projectsToRemove[0].project, 'project b');
    });
  });
</script>
