<!DOCTYPE html>
<!--
@license
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">
<meta charset="utf-8">
<title>gr-settings-view</title>

<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>

<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>

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

<script type="module">
import '../../../test/common-test-setup.js';
import './gr-menu-editor.js';
import {flush as flush$0} from '@polymer/polymer/lib/legacy/polymer.dom.js';
suite('gr-menu-editor tests', () => {
  let element;
  let menu;

  function assertMenuNamesEqual(element, expected) {
    const names = element.menuItems.map(i => i.name);
    assert.equal(names.length, expected.length);
    for (let 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) {
    const selector = 'tr:nth-child(' + (index + 1) + ') .move' +
        direction + 'Button';
    const button =
        element.shadowRoot
            .querySelector('tbody').querySelector(selector)
            .shadowRoot
            .querySelector('paper-button');
    MockInteractions.tap(button);
  }

  setup(done => {
    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);
    flush$0();
    flush(done);
  });

  test('renders', () => {
    const rows = element.shadowRoot
        .querySelector('tbody').querySelectorAll('tr');
    let tds;

    assert.equal(rows.length, menu.length);
    for (let 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', () => {
    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', () => {
    const newName = 'new name';
    const newUrl = 'new url';

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

    const 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', () => {
    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', () => {
    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', () => {
    assertMenuNamesEqual(element,
        ['first name', 'second name', 'third name']);

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

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

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

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