/**
 * @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);
  });

  test('while loading queue enter commits', async () => {
    const commitHandler = sinon.stub();
    element.addEventListener('commit', commitHandler);
    let resolvePromise: (value: AutocompleteSuggestion[]) => void;
    const blockingPromise = new Promise<AutocompleteSuggestion[]>(resolve => {
      resolvePromise = resolve;
    });
    element.query = (_: string) => blockingPromise;

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

    pressKey(inputEl(), Key.ENTER);
    await element.updateComplete;
    assert.deepEqual(element.queryStatus, {
      type: AutocompleteQueryStatusType.LOADING,
      message: 'Loading... (Handle Enter on load)',
    });

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

    assert.equal(element.suggestions.length, 0);
    assert.isUndefined(element.queryStatus);
    assert.isTrue(commitHandler.called);
  });

  test('while loading queue tab completes', async () => {
    element.tabComplete = true;
    const commitHandler = sinon.stub();
    element.addEventListener('commit', commitHandler);
    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...',
    });

    pressKey(inputEl(), Key.TAB);
    await element.updateComplete;
    assert.deepEqual(element.queryStatus, {
      type: AutocompleteQueryStatusType.LOADING,
      message: 'Loading... (Handle Tab on load)',
    });

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

    assert.equal(element.suggestions.length, 0);
    assert.isUndefined(element.queryStatus);
    assert.isFalse(commitHandler.called);
    assert.equal(element.text, 'suggestion 1');
  });

  test('while loading and queued update text cancels', async () => {
    const commitHandler = sinon.stub();
    element.addEventListener('commit', commitHandler);
    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...',
    });

    pressKey(inputEl(), Key.ENTER);
    await element.updateComplete;
    assert.deepEqual(element.queryStatus, {
      type: AutocompleteQueryStatusType.LOADING,
      message: 'Loading... (Handle Enter on load)',
    });

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

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

    // Commit for stale request is not called.
    assert.isFalse(commitHandler.called);
  });

  test('while loading and queued esc cancels', async () => {
    const commitHandler = sinon.stub();
    element.addEventListener('commit', commitHandler);
    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...',
    });

    pressKey(inputEl(), Key.ENTER);
    await element.updateComplete;
    assert.deepEqual(element.queryStatus, {
      type: AutocompleteQueryStatusType.LOADING,
      message: 'Loading... (Handle Enter on load)',
    });

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

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

    // Commit for stale request is not called.
    assert.isFalse(commitHandler.called);
    // Query results and status are cleared
    assert.equal(element.suggestions.length, 0);
    assert.isUndefined(element.queryStatus);
  });

  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('enter with modifier does not complete', async () => {
    const commitStub = sinon.stub(element, 'handleInputCommit');

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

    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'));
    });
  });
});
