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

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

<script>
  suite('gr-settings-view tests', function() {
    var element;
    var menu;

    function assertMenuNamesEqual(element, expected) {
      var names = element.menuItems.map(function(i) { return i.name; });
      assert.equal(names.length, expected.length);
      for (var i = 0; i < names.length; i++) {
        assert.equal(names[i], expected[i]);
      }
    }

    // Click the up/down button (according to direction) for the index'th row.
    // The index of the first row is 0, corresponding to the array.
    function move(element, index, direction) {
      var selector =
          'tr:nth-child(' + (index + 1) + ') .move-' + direction + '-button';
      var button = element.$$('tbody').querySelector(selector);
      MockInteractions.tap(button);
    }

    setup(function() {
      element = fixture('basic');
      menu = [
        {url: '/first/url', name: 'first name', target: '_blank'},
        {url: '/second/url', name: 'second name', target: '_blank'},
        {url: '/third/url', name: 'third name', target: '_blank'},
      ];
      element.set('menuItems', menu);
      Polymer.dom.flush();
    });

    test('renders', function() {
      var rows = element.$$('tbody').querySelectorAll('tr');
      var tds;

      assert.equal(rows.length, menu.length);
      for (var i = 0; i < menu.length; i++) {
        tds = rows[i].querySelectorAll('td');
        assert.equal(tds[0].textContent, menu[i].name);
        assert.equal(tds[1].textContent, menu[i].url);
      }

      assert.isTrue(element._computeAddDisabled(element._newName,
          element._newUrl));
    });

    test('_computeAddDisabled', function() {
      assert.isTrue(element._computeAddDisabled('', ''));
      assert.isTrue(element._computeAddDisabled('name', ''));
      assert.isTrue(element._computeAddDisabled('', 'url'));
      assert.isFalse(element._computeAddDisabled('name', 'url'));
    });

    test('add a new menu item', function() {
      var newName = 'new name';
      var newUrl = 'new url';

      element._newName = newName;
      element._newUrl = newUrl;
      assert.isFalse(element._computeAddDisabled(element._newName,
          element._newUrl));

      var originalMenuLength = element.menuItems.length;

      element._handleAddButton();

      assert.equal(element.menuItems.length, originalMenuLength + 1);
      assert.equal(element.menuItems[element.menuItems.length - 1].name,
          newName);
      assert.equal(element.menuItems[element.menuItems.length - 1].url, newUrl);
    });

    test('move items down', function() {
      assertMenuNamesEqual(element,
          ['first name', 'second name', 'third name']);

      // Move the middle item down
      move(element, 1, 'down');
      assertMenuNamesEqual(element,
          ['first name', 'third name', 'second name']);

      // Moving the bottom item down is a no-op.
      move(element, 2, 'down');
      assertMenuNamesEqual(element,
          ['first name', 'third name', 'second name']);
    });

    test('move items up', function() {
      assertMenuNamesEqual(element,
          ['first name', 'second name', 'third name']);

      // Move the last item up twice to be the first.
      move(element, 2, 'up');
      move(element, 1, 'up');
      assertMenuNamesEqual(element,
          ['third name', 'first name', 'second name']);

      // Moving the top item up is a no-op.
      move(element, 0, 'up');
      assertMenuNamesEqual(element,
          ['third name', 'first name', 'second name']);
    });

    test('remove item', function() {
      assertMenuNamesEqual(element,
          ['first name', 'second name', 'third name']);

      // Tap the delete button for the middle item.
      MockInteractions.tap(
          element.$$('tbody').querySelector('tr:nth-child(2) .remove-button'));

      assertMenuNamesEqual(element, ['first name', 'third name']);

      // Delete remaining items.
      for (var i = 0; i < 2; i++) {
        MockInteractions.tap(
            element.$$('tbody').querySelector('tr:first-child .remove-button'));
      }
      assertMenuNamesEqual(element, []);

      // Add item to empty menu.
      element._newName = 'new name';
      element._newUrl = 'new url';
      element._handleAddButton();
      assertMenuNamesEqual(element, ['new name']);
    });
  });
</script>
