/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../test/common-test-setup';
import './gr-autocomplete';
import {AutocompleteSuggestion, GrAutocomplete} from './gr-autocomplete';
import {
  assertFails,
  mockPromise,
  pressKey,
  queryAndAssert,
  waitUntil,
} from '../../../test/test-utils';
import {
  AutocompleteQueryStatusType,
  GrAutocompleteDropdown,
} from '../gr-autocomplete-dropdown/gr-autocomplete-dropdown';
import {PaperInputElement} from '@polymer/paper-input/paper-input';
import {fixture, html, assert} from '@open-wc/testing';
import {Key, Modifier} from '../../../utils/dom-util';

suite('gr-autocomplete tests', () => {
  let element: GrAutocomplete;

  const focusOnInput = () => {
    pressKey(inputEl(), Key.ENTER);
  };

  const suggestionsEl = () =>
    queryAndAssert<GrAutocompleteDropdown>(element, '#suggestions');

  const inputEl = () => queryAndAssert<HTMLInputElement>(element, '#input');

  setup(async () => {
    element = await fixture(html`<gr-autocomplete></gr-autocomplete>`);
  });

  test('renders', () => {
    assert.shadowDom.equal(
      element,
      /* HTML */ `
        <paper-input
          aria-disabled="false"
          autocomplete="off"
          id="input"
          tabindex="0"
        >
          <div slot="prefix">
            <slot name="prefix"> </slot>
          </div>
          <div slot="suffix">
            <slot name="suffix"> </slot>
          </div>
        </paper-input>
        <gr-autocomplete-dropdown
          id="suggestions"
          is-hidden=""
          role="listbox"
          style="position: fixed; top: 300px; left: 392.5px; box-sizing: border-box; max-height: 600px; max-width: 785px;"
        >
        </gr-autocomplete-dropdown>
      `,
      {
        // gr-autocomplete-dropdown sizing seems to vary between local & CI
        ignoreAttributes: [
          {tags: ['gr-autocomplete-dropdown'], attributes: ['style']},
        ],
      }
    );
  });

  test('renders with suggestions', async () => {
    const queryStub = sinon.spy((input: string) =>
      Promise.resolve([
        {name: input + ' 0', value: '0'},
        {name: input + ' 1', value: '1'},
        {name: input + ' 2', value: '2'},
        {name: input + ' 3', value: '3'},
        {name: input + ' 4', value: '4'},
      ] as AutocompleteSuggestion[])
    );
    element.query = queryStub;

    focusOnInput();
    element.text = 'blah';
    await waitUntil(() => queryStub.called);
    await element.updateComplete;

    assert.shadowDom.equal(
      element,
      /* HTML */ `
        <paper-input
          aria-disabled="false"
          autocomplete="off"
          id="input"
          tabindex="0"
        >
          <div slot="prefix">
            <slot name="prefix"> </slot>
          </div>
          <div slot="suffix">
            <slot name="suffix"> </slot>
          </div>
        </paper-input>
        <gr-autocomplete-dropdown id="suggestions" role="listbox">
        </gr-autocomplete-dropdown>
      `,
      {
        // gr-autocomplete-dropdown sizing seems to vary between local & CI
        ignoreAttributes: [
          {tags: ['gr-autocomplete-dropdown'], attributes: ['style']},
        ],
      }
    );
  });

  test('renders with error', async () => {
    const queryStub = sinon.spy((input: string) =>
      Promise.reject(new Error(`${input} not allowed`))
    );
    element.query = queryStub;

    focusOnInput();
    element.text = 'blah';
    await waitUntil(() => queryStub.called);
    await element.updateComplete;

    assert.shadowDom.equal(
      element,
      /* HTML */ `
        <paper-input
          aria-disabled="false"
          autocomplete="off"
          id="input"
          tabindex="0"
        >
          <div slot="prefix">
            <slot name="prefix"> </slot>
          </div>
          <div slot="suffix">
            <slot name="suffix"> </slot>
          </div>
        </paper-input>
        <gr-autocomplete-dropdown id="suggestions" role="listbox">
        </gr-autocomplete-dropdown>
      `,
      {
        // gr-autocomplete-dropdown sizing seems to vary between local & CI
        ignoreAttributes: [
          {tags: ['gr-autocomplete-dropdown'], attributes: ['style']},
        ],
      }
    );
    assert.equal(
      element.suggestionsDropdown?.queryStatus?.message,
      'blah not allowed'
    );
  });

  test('cursor starts on suggestions', async () => {
    const queryStub = sinon.spy((input: string) =>
      Promise.resolve([
        {name: input + ' 0', value: '0'},
        {name: input + ' 1', value: '1'},
        {name: input + ' 2', value: '2'},
        {name: input + ' 3', value: '3'},
        {name: input + ' 4', value: '4'},
      ] as AutocompleteSuggestion[])
    );
    element.query = queryStub;

    assert.equal(suggestionsEl().cursor.index, -1);

    focusOnInput();
    element.text = 'blah';
    await waitUntil(() => queryStub.called);
    await element.updateComplete;

    assert.notEqual(suggestionsEl().cursor.index, -1);
  });

  test('selectAll', async () => {
    await element.updateComplete;
    const nativeInput = element.nativeInput;
    const selectionStub = sinon.stub(nativeInput, 'setSelectionRange');

    element.selectAll();
    await element.updateComplete;
    assert.isFalse(selectionStub.called);

    inputEl().value = 'test';
    await element.updateComplete;
    element.selectAll();
    assert.isTrue(selectionStub.called);
  });

  test('esc key behavior', async () => {
    let promise: Promise<AutocompleteSuggestion[]> = Promise.resolve([]);
    const queryStub = sinon.spy(
      (_: string) =>
        (promise = Promise.resolve([
          {name: 'blah', value: '123'},
        ] as AutocompleteSuggestion[]))
    );
    element.query = queryStub;

    assert.isTrue(suggestionsEl().isHidden);

    element.setFocus(true);
    element.text = 'blah';
    await element.updateComplete;

    return promise.then(async () => {
      await waitUntil(() => !suggestionsEl().isHidden);

      const cancelHandler = sinon.spy();
      element.addEventListener('cancel', cancelHandler);

      pressKey(inputEl(), Key.ESC);
      await waitUntil(() => suggestionsEl().isHidden);

      assert.isFalse(cancelHandler.called);
      assert.equal(element.suggestions.length, 0);

      pressKey(inputEl(), Key.ESC);
      await element.updateComplete;

      assert.isTrue(cancelHandler.called);
    });
  });

  test('esc key behavior on error', async () => {
    let promise: Promise<AutocompleteSuggestion[]> = Promise.resolve([]);
    const queryStub = sinon.spy(
      (_: string) => (promise = Promise.reject(new Error('Test error')))
    );
    element.query = queryStub;

    assert.isTrue(suggestionsEl().isHidden);

    element.setFocus(true);
    element.text = 'blah';
    await element.updateComplete;

    return assertFails(promise).then(async () => {
      await element.latestSuggestionUpdateComplete;
      await waitUntil(() => !suggestionsEl().isHidden);

      const cancelHandler = sinon.spy();
      element.addEventListener('cancel', cancelHandler);
      assert.deepEqual(element.queryStatus, {
        type: AutocompleteQueryStatusType.ERROR,
        message: 'Test error',
      });

      pressKey(inputEl(), Key.ESC);
      await waitUntil(() => suggestionsEl().isHidden);

      assert.isFalse(cancelHandler.called);
      assert.isUndefined(element.queryStatus);

      pressKey(inputEl(), Key.ESC);
      await element.updateComplete;

      assert.isTrue(cancelHandler.called);
    });
  });

  test('emits commit and handles cursor movement', async () => {
    const queryStub = sinon.spy((input: string) =>
      Promise.resolve([
        {name: input + ' 0', value: '0'},
        {name: input + ' 1', value: '1'},
        {name: input + ' 2', value: '2'},
        {name: input + ' 3', value: '3'},
        {name: input + ' 4', value: '4'},
      ] as AutocompleteSuggestion[])
    );
    element.query = queryStub;
    await element.updateComplete;
    assert.isTrue(suggestionsEl().isHidden);
    assert.equal(suggestionsEl().cursor.index, -1);
    element.setFocus(true);

    element.text = 'blah';
    await element.updateComplete;

    return element.latestSuggestionUpdateComplete!.then(async () => {
      await waitUntil(() => !suggestionsEl().isHidden);

      const commitHandler = sinon.spy();
      element.addEventListener('commit', commitHandler);

      assert.equal(suggestionsEl().cursor.index, 0);

      pressKey(inputEl(), 'ArrowDown');
      await element.updateComplete;

      assert.equal(suggestionsEl().cursor.index, 1);

      pressKey(inputEl(), 'ArrowDown');
      await element.updateComplete;

      assert.equal(suggestionsEl().cursor.index, 2);

      pressKey(inputEl(), 'ArrowUp');
      await element.updateComplete;

      assert.equal(suggestionsEl().cursor.index, 1);

      pressKey(inputEl(), Key.ENTER);
      await element.updateComplete;

      assert.equal(element.value, '1');

      await waitUntil(() => commitHandler.called);
      assert.equal(commitHandler.getCall(0).args[0].detail.value, 1);
      assert.isTrue(suggestionsEl().isHidden);
      assert.isTrue(element.focused);
    });
  });

  test('clear-on-commit behavior (off)', async () => {
    let promise: Promise<AutocompleteSuggestion[]> = Promise.resolve([]);
    const queryStub = sinon.spy(() => {
      promise = Promise.resolve([
        {name: 'suggestion', value: '0'},
      ] as AutocompleteSuggestion[]);
      return promise;
    });
    element.query = queryStub;
    focusOnInput();
    element.text = 'blah';
    await waitUntil(() => element.suggestions.length > 0);

    return promise.then(async () => {
      const commitHandler = sinon.spy();
      element.addEventListener('commit', commitHandler);

      pressKey(inputEl(), Key.ENTER);

      await waitUntil(() => commitHandler.called);

      assert.equal(element.text, 'suggestion');
    });
  });

  test('clear-on-commit behavior (on)', async () => {
    let promise: Promise<AutocompleteSuggestion[]> = Promise.resolve([]);
    const queryStub = sinon.spy(() => {
      promise = Promise.resolve([
        {name: 'suggestion', value: '0'},
      ] as AutocompleteSuggestion[]);
      return promise;
    });
    element.query = queryStub;
    focusOnInput();
    element.text = 'blah';

    await waitUntil(() => element.suggestions.length > 0);

    element.clearOnCommit = true;

    return promise.then(async () => {
      const commitHandler = sinon.spy();
      element.addEventListener('commit', commitHandler);

      pressKey(inputEl(), Key.ENTER);

      await waitUntil(() => commitHandler.called);

      assert.equal(element.text, '');
    });
  });

  test('threshold guards the query', async () => {
    const queryStub = sinon.spy(() =>
      Promise.resolve([] as AutocompleteSuggestion[])
    );
    element.query = queryStub;
    element.threshold = 2;
    focusOnInput();
    element.text = 'a';
    await element.updateComplete;
    assert.isFalse(queryStub.called);

    element.text = 'ab';
    await element.updateComplete;
    await waitUntil(() => queryStub.called);
  });

  test('noDebounce=false debounces the query', async () => {
    const queryStub = sinon.spy(() =>
      Promise.resolve([] as AutocompleteSuggestion[])
    );

    element.query = queryStub;
    await element.updateComplete;
    focusOnInput();
    element.text = 'a';

    // not called right away
    assert.isFalse(queryStub.called);

    await waitUntil(() => queryStub.called);
  });

  test('computeClass respects border property', () => {
    element.borderless = false;
    assert.equal(element.computeClass(), '');
    element.borderless = true;
    assert.equal(element.computeClass(), 'borderless');
    element.showBlueFocusBorder = true;
    assert.equal(element.computeClass(), 'borderless showBlueFocusBorder');
  });

  test('empty text results in no suggestions', async () => {
    element.text = '';
    element.threshold = 0;
    await element.updateComplete;
    assert.equal(element.suggestions.length, 0);
  });

  test('when focused', async () => {
    let promise: Promise<AutocompleteSuggestion[]> = Promise.resolve([]);
    const queryStub = sinon
      .stub()
      .returns(
        (promise = Promise.resolve([
          {name: 'suggestion', value: '0'},
        ] as AutocompleteSuggestion[]))
      );
    element.query = queryStub;
    focusOnInput();
    element.text = 'bla';
    assert.equal(element.focused, true);
    await element.updateComplete;
    return promise.then(async () => {
      await waitUntil(() => element.suggestions.length > 0);
      assert.equal(element.suggestions.length, 1);
      assert.equal(queryStub.notCalled, false);
    });
  });

  test('when not focused', async () => {
    let promise: Promise<AutocompleteSuggestion[]> = Promise.resolve([]);
    const queryStub = sinon
      .stub()
      .returns(
        (promise = Promise.resolve([
          {name: 'suggestion', value: '0'},
        ] as AutocompleteSuggestion[]))
      );
    element.query = queryStub;
    element.text = 'bla';
    assert.equal(element.focused, false);
    await element.updateComplete;
    return promise.then(() => {
      assert.equal(element.suggestions.length, 0);
    });
  });

  test('suggestions should not carry over', async () => {
    const queryStub = sinon
      .stub()
      .resolves([{name: 'suggestion', value: '0'}] as AutocompleteSuggestion[]);
    element.query = queryStub;
    focusOnInput();
    element.text = 'bla';
    await element.updateComplete;
    return element.latestSuggestionUpdateComplete!.then(async () => {
      await waitUntil(() => element.suggestions.length > 0);
      assert.equal(element.suggestions.length, 1);

      queryStub.resolves([] as AutocompleteSuggestion[]);
      element.text = '';
      element.threshold = 0;
      await element.updateComplete;
      await element.latestSuggestionUpdateComplete;
      assert.equal(element.suggestions.length, 0);
    });
  });

  test('error should not carry over', async () => {
    let promise: Promise<AutocompleteSuggestion[]> = Promise.resolve([]);
    const queryStub = sinon
      .stub()
      .returns((promise = Promise.reject(new Error('Test error'))));
    element.query = queryStub;
    focusOnInput();
    element.text = 'bla';
    await element.updateComplete;
    return assertFails(promise).then(async () => {
      await element.latestSuggestionUpdateComplete;
      await waitUntil(() => element.queryStatus?.message === 'Test error');

      queryStub.resolves([] as AutocompleteSuggestion[]);
      element.text = '';
      element.threshold = 0;
      await element.updateComplete;
      await element.latestSuggestionUpdateComplete;
      assert.isUndefined(element.queryStatus);
    });
  });

  test('multi completes only the last part of the query', async () => {
    let promise;
    const queryStub = sinon
      .stub()
      .returns(
        (promise = Promise.resolve([
          {name: 'suggestion', value: '0'},
        ] as AutocompleteSuggestion[]))
      );
    element.query = queryStub;
    focusOnInput();
    element.text = 'blah blah';
    element.multi = true;
    await element.updateComplete;

    return promise.then(async () => {
      const commitHandler = sinon.spy();
      element.addEventListener('commit', commitHandler);
      await element.latestSuggestionUpdateComplete;
      await waitUntil(() => element.suggestionsDropdown?.isHidden === false);

      pressKey(inputEl(), Key.ENTER);

      await waitUntil(() => commitHandler.called);
      assert.equal(element.text, 'blah 0');
    });
  });

  test('tabComplete flag functions', async () => {
    element.query = sinon
      .stub()
      .resolves([
        {name: 'tunnel snakes rule!', value: 'snakes'},
      ] as AutocompleteSuggestion[]);

    // commitHandler checks for the commit event, whereas commitSpy checks for
    // the _commit function of the element.
    const commitHandler = sinon.spy();
    element.addEventListener('commit', commitHandler);
    const commitSpy = sinon.spy(element, '_commit');
    element.setFocus(true);
    element.tabComplete = false;
    element.text = 'text1';
    await element.updateComplete;

    await element.latestSuggestionUpdateComplete;
    await element.updateComplete;
    pressKey(inputEl(), Key.TAB);
    await element.updateComplete;

    assert.isFalse(commitHandler.called);
    assert.isFalse(commitSpy.called);
    assert.isFalse(element.focused);

    element.setFocus(true);
    element.tabComplete = true;
    element.text = 'text2';
    await element.updateComplete;

    await element.latestSuggestionUpdateComplete;
    await element.updateComplete;
    pressKey(inputEl(), Key.TAB);

    await waitUntil(() => commitSpy.called);
    assert.isFalse(commitHandler.called);
    assert.isTrue(element.focused);
  });

  test('focused flag properly triggered', async () => {
    await element.updateComplete;
    assert.isFalse(element.focused);
    const input = queryAndAssert<PaperInputElement>(element, 'paper-input');
    input.focus();
    assert.isTrue(element.focused);
  });

  test('vertical offset overridden by param if it exists', async () => {
    assert.equal(suggestionsEl().verticalOffset, 31);

    element.verticalOffset = 30;
    await element.updateComplete;

    assert.equal(suggestionsEl().verticalOffset, 30);
  });

  test('focused flag shows/hides the suggestions', async () => {
    const openStub = sinon.stub(suggestionsEl(), 'open');
    const closedStub = sinon.stub(suggestionsEl(), 'close');
    element.suggestions = [{text: 'hello'}, {text: 'its me'}];
    assert.isFalse(openStub.called);
    await waitUntil(() => closedStub.calledOnce);
    element.setFocus(true);
    await waitUntil(() => openStub.calledOnce);
    element.suggestions = [];
    await waitUntil(() => closedStub.calledTwice);
    assert.isTrue(openStub.calledOnce);
  });

  test(
    'handleInputCommit with autocomplete hidden does nothing without' +
      ' allowNonSuggestedValues',
    () => {
      const commitStub = sinon.stub(element, '_commit');
      suggestionsEl().isHidden = true;
      element.handleInputCommit();
      assert.isFalse(commitStub.called);
    }
  );

  test(
    'handleInputCommit with query error does nothing without' +
      ' allowNonSuggestedValues',
    () => {
      const commitStub = sinon.stub(element, '_commit');
      element.queryStatus = {
        type: AutocompleteQueryStatusType.ERROR,
        message: 'Error',
      };
      element.suggestions = [];
      element.handleInputCommit();
      assert.isFalse(commitStub.called);
    }
  );

  test(
    'handleInputCommit with autocomplete hidden with' +
      'allowNonSuggestedValues',
    () => {
      const commitStub = sinon.stub(element, '_commit');
      element.allowNonSuggestedValues = true;
      suggestionsEl().isHidden = true;
      element.handleInputCommit();
      assert.isTrue(commitStub.called);
    }
  );

  test(
    'handleInputCommit with query error with' + 'allowNonSuggestedValues',
    () => {
      const commitStub = sinon.stub(element, '_commit');
      element.allowNonSuggestedValues = true;
      element.queryStatus = {
        type: AutocompleteQueryStatusType.ERROR,
        message: 'Error',
      };
      element.suggestions = [];
      element.handleInputCommit();
      assert.isTrue(commitStub.called);
    }
  );

  test('handleInputCommit with autocomplete open calls commit', () => {
    const commitStub = sinon.stub(element, '_commit');
    suggestionsEl().isHidden = false;
    element.suggestions = [{name: 'first suggestion'}];
    element.handleInputCommit();
    assert.isTrue(commitStub.calledOnce);
  });

  test(
    'handleInputCommit with autocomplete open calls commit' +
      'with allowNonSuggestedValues',
    () => {
      const commitStub = sinon.stub(element, '_commit');
      element.allowNonSuggestedValues = true;
      suggestionsEl().isHidden = false;
      element.handleInputCommit();
      assert.isTrue(commitStub.calledOnce);
    }
  );

  test('issue 8655', async () => {
    function makeSuggestion(s: string) {
      return {name: s, text: s, value: s};
    }
    const keydownSpy = sinon.spy(element, 'handleKeydown');
    element.requestUpdate();
    await element.updateComplete;

    // const dispatchEventStub = sinon.stub(element, 'dispatchEvent');
    element.setText('file:');
    element.suggestions = [makeSuggestion('file:'), makeSuggestion('-file:')];
    await element.updateComplete;

    pressKey(inputEl(), 'x');
    // Must set the value, because the MockInteraction does not.
    inputEl().value = 'file:x';

    assert.isTrue(keydownSpy.calledOnce);

    pressKey(inputEl(), Key.ENTER);
    await element.updateComplete;
    assert.isTrue(keydownSpy.calledTwice);

    assert.equal(element.text, 'file:x');
  });

  test('render loading replace with suggestions when done', async () => {
    const queryPromise = mockPromise<AutocompleteSuggestion[]>();
    element.query = (_: string) => queryPromise;

    element.setFocus(true);
    element.text = 'blah';
    await element.updateComplete;
    await waitUntil(() => !suggestionsEl().isHidden);
    assert.deepEqual(element.queryStatus, {
      type: AutocompleteQueryStatusType.LOADING,
      message: 'Loading...',
    });

    queryPromise.resolve([{name: 'suggestion 1'}] as AutocompleteSuggestion[]);
    await element.latestSuggestionUpdateComplete;
    await element.updateComplete;

    assert.equal(element.suggestions.length, 1);
    assert.isUndefined(element.queryStatus);
  });

  test('render loading replace with error when done', async () => {
    const queryPromise = mockPromise<AutocompleteSuggestion[]>();
    element.query = (_: string) => queryPromise;

    element.setFocus(true);
    element.text = 'blah';
    await element.updateComplete;
    await waitUntil(() => !suggestionsEl().isHidden);
    assert.deepEqual(element.queryStatus, {
      type: AutocompleteQueryStatusType.LOADING,
      message: 'Loading...',
    });

    queryPromise.reject(new Error('Test error'));
    await assertFails(queryPromise);
    await element.latestSuggestionUpdateComplete;
    await element.updateComplete;

    assert.equal(element.suggestions.length, 0);
    assert.deepEqual(element.queryStatus, {
      type: AutocompleteQueryStatusType.ERROR,
      message: 'Test error',
    });
  });

  test('render loading esc cancels', async () => {
    const queryPromise = mockPromise<AutocompleteSuggestion[]>();
    element.query = (_: string) => queryPromise;

    element.setFocus(true);
    element.text = 'blah';
    await element.updateComplete;
    await waitUntil(() => !suggestionsEl().isHidden);
    assert.deepEqual(element.queryStatus, {
      type: AutocompleteQueryStatusType.LOADING,
      message: 'Loading...',
    });

    const cancelHandler = sinon.spy();
    element.addEventListener('cancel', cancelHandler);
    pressKey(inputEl(), Key.ESC);
    await waitUntil(() => suggestionsEl().isHidden);

    assert.isFalse(cancelHandler.called);
    assert.isUndefined(element.queryStatus);

    pressKey(inputEl(), Key.ESC);
    await element.updateComplete;

    assert.isTrue(cancelHandler.called);
  });

  suite('focus', () => {
    let commitSpy: sinon.SinonSpy;
    let focusSpy: sinon.SinonSpy;

    setup(() => {
      commitSpy = sinon.spy(element, '_commit');
    });

    test('enter in input does not re-render suggestions', async () => {
      element.suggestions = [{text: 'sugar bombs'}];

      pressKey(inputEl(), Key.ENTER);

      await waitUntil(() => commitSpy.called);
      await element.updateComplete;

      assert.equal(element.suggestions.length, 0);
      assert.isUndefined(element.queryStatus);
      assert.isTrue(suggestionsEl().isHidden);
    });

    test('enter in input does not re-render error', async () => {
      element.allowNonSuggestedValues = true;
      element.queryStatus = {
        type: AutocompleteQueryStatusType.ERROR,
        message: 'Error message',
      };

      pressKey(inputEl(), Key.ENTER);

      await waitUntil(() => commitSpy.called);
      await element.updateComplete;

      assert.equal(element.suggestions.length, 0);
      assert.isUndefined(element.queryStatus);
      assert.isTrue(suggestionsEl().isHidden);
    });

    test('enter in suggestion does not re-render suggestions', async () => {
      element.suggestions = [{text: 'sugar bombs'}];
      element.setFocus(true);

      await element.updateComplete;
      assert.isFalse(suggestionsEl().isHidden);

      focusSpy = sinon.spy(element, 'focus');
      pressKey(suggestionsEl(), Key.ENTER);

      await waitUntil(() => commitSpy.called);
      await element.updateComplete;

      assert.equal(element.suggestions.length, 0);
      assert.isTrue(suggestionsEl().isHidden);
    });

    test('tab in input, tabComplete = true', async () => {
      focusSpy = sinon.spy(element, 'focus');
      const commitHandler = sinon.stub();
      element.addEventListener('commit', commitHandler);
      element.tabComplete = true;
      element.suggestions = [{text: 'tunnel snakes drool'}];

      pressKey(inputEl(), Key.TAB);

      await waitUntil(() => commitSpy.called);

      assert.isTrue(focusSpy.called);
      assert.isFalse(commitHandler.called);
      assert.equal(element.suggestions.length, 0);
    });

    test('tab in input, tabComplete = false', async () => {
      element.suggestions = [{text: 'sugar bombs'}];
      focusSpy = sinon.spy(element, 'focus');
      pressKey(inputEl(), Key.TAB);
      await element.updateComplete;

      assert.isFalse(commitSpy.called);
      assert.isFalse(focusSpy.called);
      await waitUntil(() => element.suggestions.length > 0);
      assert.equal(element.suggestions.length, 1);
    });

    test('tab on suggestion, tabComplete = false', async () => {
      element.suggestions = [{name: 'sugar bombs'}];
      element.setFocus(true);
      // When tabComplete is false, do not focus.
      element.tabComplete = false;
      focusSpy = sinon.spy(element, 'focus');

      await element.updateComplete;

      assert.isFalse(suggestionsEl().isHidden);

      pressKey(queryAndAssert(suggestionsEl(), 'li:first-child'), Key.TAB);
      await element.updateComplete;
      assert.isFalse(commitSpy.called);
      assert.isFalse(element.focused);
    });

    test('tab on suggestion, tabComplete = true', async () => {
      element.suggestions = [{name: 'sugar bombs'}];
      element.setFocus(true);
      // When tabComplete is true, focus.
      element.tabComplete = true;
      focusSpy = sinon.spy(element, 'focus');

      await element.updateComplete;

      assert.isFalse(suggestionsEl().isHidden);

      pressKey(queryAndAssert(suggestionsEl(), 'li:first-child'), Key.TAB);
      await element.updateComplete;

      assert.isTrue(commitSpy.called);
      assert.isTrue(element.focused);
    });

    test('tap on suggestion commits, calls focus', async () => {
      focusSpy = sinon.spy(element, 'focus');
      element.setFocus(true);
      element.suggestions = [{name: 'first suggestion'}];

      await element.updateComplete;

      await waitUntil(() => !suggestionsEl().isHidden);
      queryAndAssert<HTMLLIElement>(suggestionsEl(), 'li:first-child').click();

      await waitUntil(() => suggestionsEl().isHidden);
      assert.isTrue(focusSpy.called);
      assert.isTrue(commitSpy.called);
    });

    test('esc on suggestion clears suggestions, calls focus', async () => {
      element.suggestions = [{name: 'sugar bombs'}];
      element.setFocus(true);
      focusSpy = sinon.spy(element, 'focus');

      await element.updateComplete;

      assert.isFalse(suggestionsEl().isHidden);

      pressKey(queryAndAssert(suggestionsEl(), 'li:first-child'), Key.ESC);

      await waitUntil(() => suggestionsEl().isHidden);
      await element.updateComplete;

      assert.isFalse(commitSpy.called);
      assert.isTrue(focusSpy.called);
    });
  });

  test('input-keydown event fired', async () => {
    const listener = sinon.spy();
    element.addEventListener('input-keydown', listener);
    pressKey(inputEl(), Key.TAB);
    await element.updateComplete;
    assert.isTrue(listener.called);
  });

  test('enter with modifier does not complete', async () => {
    const dispatchEventStub = sinon.stub(element, 'dispatchEvent');
    const commitStub = sinon.stub(element, 'handleInputCommit');
    pressKey(inputEl(), Key.ENTER, Modifier.CTRL_KEY);
    await element.updateComplete;

    assert.equal(dispatchEventStub.lastCall.args[0].type, 'input-keydown');
    assert.equal(
      (dispatchEventStub.lastCall.args[0] as CustomEvent).detail.key,
      Key.ENTER
    );

    assert.isFalse(commitStub.called);
    pressKey(inputEl(), Key.ENTER);
    await element.updateComplete;

    assert.isTrue(commitStub.called);
  });

  test('enter with dropdown does not propagate', async () => {
    const event = new KeyboardEvent('keydown', {key: Key.ENTER});
    const stopPropagationStub = sinon.stub(event, 'stopPropagation');

    element.suggestions = [{name: 'first suggestion'}];

    inputEl().dispatchEvent(event);
    await element.updateComplete;

    assert.isTrue(stopPropagationStub.called);
  });

  test('enter with no dropdown propagates', async () => {
    const event = new KeyboardEvent('keydown', {key: Key.ENTER});
    const stopPropagationStub = sinon.stub(event, 'stopPropagation');

    inputEl().dispatchEvent(event);
    await element.updateComplete;

    assert.isFalse(stopPropagationStub.called);
  });

  suite('warnUncommitted', () => {
    let inputClassList: DOMTokenList;
    setup(() => {
      inputClassList = inputEl().classList;
    });

    test('enabled', () => {
      element.warnUncommitted = true;
      element.text = 'blah blah blah';
      inputEl().dispatchEvent(new Event('blur'));
      assert.isTrue(inputClassList.contains('warnUncommitted'));
      inputEl().focus();
      assert.isFalse(inputClassList.contains('warnUncommitted'));
    });

    test('disabled', () => {
      element.warnUncommitted = false;
      element.text = 'blah blah blah';
      inputEl().blur();
      assert.isFalse(inputClassList.contains('warnUncommitted'));
    });

    test('no text', () => {
      element.warnUncommitted = true;
      element.text = '';
      inputEl().blur();
      assert.isFalse(inputClassList.contains('warnUncommitted'));
    });
  });
});
