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

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

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

<script>
  suite('gr-change-table-editor tests', () => {
    let element;
    let columns;
    let sandbox;

    setup(() => {
      element = fixture('basic');
      sandbox = sinon.sandbox.create();

      columns = [
        'Subject',
        'Status',
        'Owner',
        'Project',
        'Branch',
        'Updated',
      ];

      element.set('displayedColumns', columns);
      flushAsynchronousOperations();
    });

    teardown(() => {
      sandbox.restore();
    });

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

      assert.equal(rows.length, element.columnNames.length);
      for (let i = 0; i < columns.length; i++) {
        tds = rows[i].querySelectorAll('td');
        assert.equal(tds[0].textContent, columns[i]);
      }
    });

    test('hide item', () => {
      const checkbox = element.$$('table input');
      const isChecked = checkbox.checked;
      const displayedLength = element.displayedColumns.length;
      assert.isTrue(isChecked);

      MockInteractions.tap(checkbox);
      flushAsynchronousOperations();

      assert.equal(element.displayedColumns.length,
          displayedLength - 1);
    });

    test('show item', () => {
      element.set('displayedColumns', [
        'Status',
        'Owner',
        'Project',
        'Branch',
        'Updated',
      ]);
      flushAsynchronousOperations();
      const checkbox = element.$$('table input');
      const isChecked = checkbox.checked;
      const displayedLength = element.displayedColumns.length;
      assert.isFalse(isChecked);
      assert.equal(element.$$('table').style.display, '');

      MockInteractions.tap(checkbox);
      flushAsynchronousOperations();

      assert.equal(element.displayedColumns.length,
          displayedLength + 1);
    });

    test('_handleTargetTap', () => {
      const checkbox = element.$$('table input');
      let originalDisplayedColumns = element.displayedColumns;
      const td = element.$$('table .checkboxContainer');
      const displayedColumnStub =
          sandbox.stub(element, '_updateDisplayedColumns');

      MockInteractions.tap(checkbox);
      assert.isTrue(displayedColumnStub.lastCall.calledWithExactly(
          originalDisplayedColumns,
          checkbox.name,
          checkbox.checked));

      originalDisplayedColumns = element.displayedColumns;
      MockInteractions.tap(td);
      assert.isTrue(displayedColumnStub.lastCall.calledWithExactly(
          originalDisplayedColumns,
          checkbox.name,
          checkbox.checked));
    });

    test('_updateDisplayedColumns', () => {
      let name = 'Subject';
      let checked = false;
      assert.deepEqual(element._updateDisplayedColumns(columns, name, checked),
          [
            'Status',
            'Owner',
            'Project',
            'Branch',
            'Updated',
          ]);
      name = 'Size';
      checked = true;
      assert.deepEqual(element._updateDisplayedColumns(columns, name, checked),
          [
            'Subject',
            'Status',
            'Owner',
            'Project',
            'Branch',
            'Updated',
            'Size',
          ]);
    });
  });
</script>
