<!--
@license
Copyright (C) 2017 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-editor-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-editor-view></gr-editor-view>
  </template>
</test-fixture>

<script type="module">
import '../../../test/common-test-setup.js';
import './gr-editor-view.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';

suite('gr-editor-view tests', () => {
  let element;
  let sandbox;
  let savePathStub;
  let saveFileStub;
  let changeDetailStub;
  let navigateStub;
  const mockParams = {
    changeNum: '42',
    path: 'foo/bar.baz',
    patchNum: 'edit',
  };

  setup(() => {
    stub('gr-rest-api-interface', {
      getLoggedIn() { return Promise.resolve(true); },
      getEditPreferences() { return Promise.resolve({}); },
    });
    sandbox = sinon.sandbox.create();
    element = fixture('basic');
    savePathStub = sandbox.stub(element.$.restAPI, 'renameFileInChangeEdit');
    saveFileStub = sandbox.stub(element.$.restAPI, 'saveChangeEdit');
    changeDetailStub = sandbox.stub(element.$.restAPI, 'getDiffChangeDetail');
    navigateStub = sandbox.stub(element, '_viewEditInChangeView');
  });

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

  suite('_paramsChanged', () => {
    test('incorrect view returns immediately', () => {
      element._paramsChanged(
          Object.assign({}, mockParams, {view: GerritNav.View.DIFF}));
      assert.notOk(element._changeNum);
    });

    test('good params proceed', () => {
      changeDetailStub.returns(Promise.resolve({}));
      const fileStub = sandbox.stub(element, '_getFileData', () => {
        element._content = 'text';
        element._newContent = 'text';
        element._type = 'application/octet-stream';
      });

      const promises = element._paramsChanged(
          Object.assign({}, mockParams, {view: GerritNav.View.EDIT}));

      flushAsynchronousOperations();
      assert.equal(element._changeNum, mockParams.changeNum);
      assert.equal(element._path, mockParams.path);
      assert.deepEqual(changeDetailStub.lastCall.args[0],
          mockParams.changeNum);
      assert.deepEqual(fileStub.lastCall.args,
          [mockParams.changeNum, mockParams.path, mockParams.patchNum]);

      return promises.then(() => {
        assert.equal(element._content, 'text');
        assert.equal(element._newContent, 'text');
        assert.equal(element._type, 'application/octet-stream');
      });
    });
  });

  test('edit file path', () => {
    element._changeNum = mockParams.changeNum;
    element._path = mockParams.path;
    savePathStub.onFirstCall().returns(Promise.resolve({}));
    savePathStub.onSecondCall().returns(Promise.resolve({ok: true}));

    // Calling with the same path should not navigate.
    return element._handlePathChanged({detail: mockParams.path}).then(() => {
      assert.isFalse(savePathStub.called);
      // !ok response
      element._handlePathChanged({detail: 'newPath'}).then(() => {
        assert.isTrue(savePathStub.called);
        assert.isFalse(navigateStub.called);
        // ok response
        element._handlePathChanged({detail: 'newPath'}).then(() => {
          assert.isTrue(navigateStub.called);
          assert.isTrue(element._successfulSave);
        });
      });
    });
  });

  test('reacts to content-change event', () => {
    const storeStub = sandbox.spy(element.$.storage, 'setEditableContentItem');
    element._newContent = 'test';
    element.$.editorEndpoint.dispatchEvent(new CustomEvent('content-change', {
      bubbles: true, composed: true,
      detail: {value: 'new content value'},
    }));
    element.flushDebouncer('store');
    flushAsynchronousOperations();

    assert.equal(element._newContent, 'new content value');
    assert.isTrue(storeStub.called);
    assert.equal(storeStub.lastCall.args[1], 'new content value');
  });

  suite('edit file content', () => {
    const originalText = 'file text';
    const newText = 'file text changed';

    setup(() => {
      element._changeNum = mockParams.changeNum;
      element._path = mockParams.path;
      element._content = originalText;
      element._newContent = originalText;
      flushAsynchronousOperations();
    });

    test('initial load', () => {
      assert.equal(element.$.file.fileContent, originalText);
      assert.isTrue(element.$.save.hasAttribute('disabled'));
    });

    test('file modification and save, !ok response', () => {
      const saveSpy = sandbox.spy(element, '_saveEdit');
      const eraseStub = sandbox.stub(element.$.storage,
          'eraseEditableContentItem');
      const alertStub = sandbox.stub(element, '_showAlert');
      saveFileStub.returns(Promise.resolve({ok: false}));
      element._newContent = newText;
      flushAsynchronousOperations();

      assert.isFalse(element.$.save.hasAttribute('disabled'));
      assert.isFalse(element._saving);

      MockInteractions.tap(element.$.save);
      assert.isTrue(saveSpy.called);
      assert.equal(alertStub.lastCall.args[0], 'Saving changes...');
      assert.isTrue(element._saving);
      assert.isTrue(element.$.save.hasAttribute('disabled'));

      return saveSpy.lastCall.returnValue.then(() => {
        assert.isTrue(saveFileStub.called);
        assert.isTrue(eraseStub.called);
        assert.isFalse(element._saving);
        assert.equal(alertStub.lastCall.args[0], 'Failed to save changes');
        assert.deepEqual(saveFileStub.lastCall.args,
            [mockParams.changeNum, mockParams.path, newText]);
        assert.isFalse(navigateStub.called);
        assert.isFalse(element.$.save.hasAttribute('disabled'));
        assert.notEqual(element._content, element._newContent);
      });
    });

    test('file modification and save', () => {
      const saveSpy = sandbox.spy(element, '_saveEdit');
      const alertStub = sandbox.stub(element, '_showAlert');
      saveFileStub.returns(Promise.resolve({ok: true}));
      element._newContent = newText;
      flushAsynchronousOperations();

      assert.isFalse(element._saving);
      assert.isFalse(element.$.save.hasAttribute('disabled'));

      MockInteractions.tap(element.$.save);
      assert.isTrue(saveSpy.called);
      assert.equal(alertStub.lastCall.args[0], 'Saving changes...');
      assert.isTrue(element._saving);
      assert.isTrue(element.$.save.hasAttribute('disabled'));

      return saveSpy.lastCall.returnValue.then(() => {
        assert.isTrue(saveFileStub.called);
        assert.isFalse(element._saving);
        assert.equal(alertStub.lastCall.args[0], 'All changes saved');
        assert.isFalse(navigateStub.called);
        assert.isTrue(element.$.save.hasAttribute('disabled'));
        assert.equal(element._content, element._newContent);
        assert.isTrue(element._successfulSave);
      });
    });

    test('file modification and close', () => {
      const closeSpy = sandbox.spy(element, '_handleCloseTap');
      element._newContent = newText;
      flushAsynchronousOperations();

      assert.isFalse(element.$.save.hasAttribute('disabled'));

      MockInteractions.tap(element.$.close);
      assert.isTrue(closeSpy.called);
      assert.isFalse(saveFileStub.called);
      assert.isTrue(navigateStub.called);
    });
  });

  suite('_getFileData', () => {
    setup(() => {
      element._newContent = 'initial';
      element._content = 'initial';
      element._type = 'initial';
      sandbox.stub(element.$.storage, 'getEditableContentItem').returns(null);
    });

    test('res.ok', () => {
      sandbox.stub(element.$.restAPI, 'getFileContent')
          .returns(Promise.resolve({
            ok: true,
            type: 'text/javascript',
            content: 'new content',
          }));

      // Ensure no data is set with a bad response.
      return element._getFileData('1', 'test/path', 'edit').then(() => {
        assert.equal(element._newContent, 'new content');
        assert.equal(element._content, 'new content');
        assert.equal(element._type, 'text/javascript');
      });
    });

    test('!res.ok', () => {
      sandbox.stub(element.$.restAPI, 'getFileContent')
          .returns(Promise.resolve({}));

      // Ensure no data is set with a bad response.
      return element._getFileData('1', 'test/path', 'edit').then(() => {
        assert.equal(element._newContent, '');
        assert.equal(element._content, '');
        assert.equal(element._type, '');
      });
    });

    test('content is undefined', () => {
      sandbox.stub(element.$.restAPI, 'getFileContent')
          .returns(Promise.resolve({
            ok: true,
            type: 'text/javascript',
          }));

      return element._getFileData('1', 'test/path', 'edit').then(() => {
        assert.equal(element._newContent, '');
        assert.equal(element._content, '');
        assert.equal(element._type, 'text/javascript');
      });
    });

    test('content and type is undefined', () => {
      sandbox.stub(element.$.restAPI, 'getFileContent')
          .returns(Promise.resolve({
            ok: true,
          }));

      return element._getFileData('1', 'test/path', 'edit').then(() => {
        assert.equal(element._newContent, '');
        assert.equal(element._content, '');
        assert.equal(element._type, '');
      });
    });
  });

  test('_showAlert', done => {
    element.addEventListener('show-alert', e => {
      assert.deepEqual(e.detail, {message: 'test message'});
      assert.isTrue(e.bubbles);
      done();
    });

    element._showAlert('test message');
  });

  test('_viewEditInChangeView respects _patchNum', () => {
    navigateStub.restore();
    const navStub = sandbox.stub(GerritNav, 'navigateToChange');
    element._patchNum = element.EDIT_NAME;
    element._viewEditInChangeView();
    assert.equal(navStub.lastCall.args[1], element.EDIT_NAME);
    element._patchNum = '1';
    element._viewEditInChangeView();
    assert.equal(navStub.lastCall.args[1], '1');
    element._successfulSave = true;
    element._viewEditInChangeView();
    assert.equal(navStub.lastCall.args[1], element.EDIT_NAME);
  });

  suite('keyboard shortcuts', () => {
    // Used as the spy on the handler for each entry in keyBindings.
    let handleSpy;

    suite('_handleSaveShortcut', () => {
      let saveStub;
      setup(() => {
        handleSpy = sandbox.spy(element, '_handleSaveShortcut');
        saveStub = sandbox.stub(element, '_saveEdit');
      });

      test('save enabled', () => {
        element._content = '';
        element._newContent = '_test';
        MockInteractions.pressAndReleaseKeyOn(element, 83, 'ctrl', 's');
        flushAsynchronousOperations();

        assert.isTrue(handleSpy.calledOnce);
        assert.isTrue(saveStub.calledOnce);

        MockInteractions.pressAndReleaseKeyOn(element, 83, 'meta', 's');
        flushAsynchronousOperations();

        assert.equal(handleSpy.callCount, 2);
        assert.equal(saveStub.callCount, 2);
      });

      test('save disabled', () => {
        MockInteractions.pressAndReleaseKeyOn(element, 83, 'ctrl', 's');
        flushAsynchronousOperations();

        assert.isTrue(handleSpy.calledOnce);
        assert.isFalse(saveStub.called);

        MockInteractions.pressAndReleaseKeyOn(element, 83, 'meta', 's');
        flushAsynchronousOperations();

        assert.equal(handleSpy.callCount, 2);
        assert.isFalse(saveStub.called);
      });
    });
  });

  suite('gr-storage caching', () => {
    test('local edit exists', () => {
      sandbox.stub(element.$.storage, 'getEditableContentItem')
          .returns({message: 'pending edit'});
      sandbox.stub(element.$.restAPI, 'getFileContent')
          .returns(Promise.resolve({
            ok: true,
            type: 'text/javascript',
            content: 'old content',
          }));

      const alertStub = sandbox.stub();
      element.addEventListener('show-alert', alertStub);

      return element._getFileData(1, 'test', 1).then(() => {
        flushAsynchronousOperations();

        assert.isTrue(alertStub.called);
        assert.equal(element._newContent, 'pending edit');
        assert.equal(element._content, 'old content');
        assert.equal(element._type, 'text/javascript');
      });
    });

    test('local edit exists, is same as remote edit', () => {
      sandbox.stub(element.$.storage, 'getEditableContentItem')
          .returns({message: 'pending edit'});
      sandbox.stub(element.$.restAPI, 'getFileContent')
          .returns(Promise.resolve({
            ok: true,
            type: 'text/javascript',
            content: 'pending edit',
          }));

      const alertStub = sandbox.stub();
      element.addEventListener('show-alert', alertStub);

      return element._getFileData(1, 'test', 1).then(() => {
        flushAsynchronousOperations();

        assert.isFalse(alertStub.called);
        assert.equal(element._newContent, 'pending edit');
        assert.equal(element._content, 'pending edit');
        assert.equal(element._type, 'text/javascript');
      });
    });

    test('storage key computation', () => {
      element._changeNum = 1;
      element._patchNum = 1;
      element._path = 'test';
      assert.equal(element.storageKey, 'c1_ps1_test');
    });
  });
});
</script>
