<!DOCTYPE html>
<!--
Copyright (C) 2015 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-reply-dialog</title>

<script src="../../../bower_components/webcomponentsjs/webcomponents.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-reply-dialog.html">

<test-fixture id="basic">
  <template>
    <gr-reply-dialog></gr-reply-dialog>
  </template>
</test-fixture>

<script>
  suite('gr-reply-dialog tests', function() {
    var element;
    var changeNum;
    var patchNum;

    var sandbox;
    var getDraftCommentStub;
    var setDraftCommentStub;
    var eraseDraftCommentStub;

    var lastId = 0;
    var makeAccount = function() { return {_account_id: lastId++}; };
    var makeGroup = function() { return {id: lastId++}; };

    setup(function() {
      sandbox = sinon.sandbox.create();

      changeNum = 42;
      patchNum = 1;

      stub('gr-rest-api-interface', {
        getConfig: function() { return Promise.resolve({}); },
        getAccount: function() { return Promise.resolve({}); },
      });

      element = fixture('basic');
      element.change = {
        _number: changeNum,
        labels: {
          Verified: {
            values: {
              '-1': 'Fails',
              ' 0': 'No score',
              '+1': 'Verified',
            },
            default_value: 0,
          },
          'Code-Review': {
            values: {
              '-2': 'Do not submit',
              '-1': 'I would prefer that you didn\'t submit this',
              ' 0': 'No score',
              '+1': 'Looks good to me, but someone else must approve',
              '+2': 'Looks good to me, approved',
            },
            default_value: 0,
          },
        },
      };
      element.patchNum = patchNum;
      element.permittedLabels = {
        'Code-Review': [
          '-1',
          ' 0',
          '+1',
        ],
        Verified: [
          '-1',
          ' 0',
          '+1',
        ],
      };
      element.serverConfig = {};

      getDraftCommentStub = sandbox.stub(element.$.storage, 'getDraftComment');
      setDraftCommentStub = sandbox.stub(element.$.storage, 'setDraftComment');
      eraseDraftCommentStub = sandbox.stub(element.$.storage,
          'eraseDraftComment');

      // Allow the elements created by dom-repeat to be stamped.
      flushAsynchronousOperations();
    });

    teardown(function() {
      sandbox.restore();
    });

    test('changes in label score are reflected in the DOM', function() {
      element._account = {_account_id: 1};
      element.set(['change', 'labels', 'Verified', 'all'],
          [{_account_id: 1, value: -1}]);
      flushAsynchronousOperations();
      var selector = element.$$('iron-selector[data-label="Verified"]');
      assert.equal(selector.selected, 0); // Index 0, value -1
      element.set(['change', 'labels', 'Verified', 'all'],
         [{_account_id: 1, value: 1}]);
      flushAsynchronousOperations();
      assert.equal(selector.selected, 2); // Index 2, value 1
    });

    test('cancel event', function(done) {
      element.addEventListener('cancel', function() { done(); });
      MockInteractions.tap(element.$$('.cancel'));
    });

    test('label picker', function(done) {
      element.revisions = {};
      element.patchNum = '';

      // Async tick is needed because iron-selector content is distributed and
      // distributed content requires an observer to be set up.
      // Note: Double flush seems to be needed in Safari. {@see Issue 4963}.
      flush(function() {
        flush(function() {
          for (var label in element.permittedLabels) {
            assert.ok(element.$$('iron-selector[data-label="' + label + '"]'),
                label);
          }
          element.draft = 'I wholeheartedly disapprove';
          MockInteractions.tap(element.$$(
              'iron-selector[data-label="Code-Review"] > ' +
              'gr-button[data-value="-1"]'));
          MockInteractions.tap(element.$$(
              'iron-selector[data-label="Verified"] > ' +
              'gr-button[data-value="-1"]'));

          var saveReviewStub = sinon.stub(element, '_saveReview',
              function(review) {
            assert.deepEqual(review, {
              drafts: 'PUBLISH_ALL_REVISIONS',
              labels: {
                'Code-Review': -1,
                'Verified': -1,
              },
              message: 'I wholeheartedly disapprove',
              reviewers: [],
            });
            return Promise.resolve({ok: true});
          });

          element.addEventListener('send', function() {
            assert.isFalse(element.disabled,
                'Element should be enabled when done sending reply.');
            assert.equal(element.draft.length, 0);
            saveReviewStub.restore();
            done();
          });

          // This is needed on non-Blink engines most likely due to the ways in
          // which the dom-repeat elements are stamped.
          flush(function() {
            MockInteractions.tap(element.$$('.send'));
            assert.isTrue(element.disabled);
          });
        });
      });
    });

    function getActiveElement() {
      return Polymer.IronOverlayManager.deepActiveElement;
    }

    function isVisible(el) {
      assert.ok(el);
      return getComputedStyle(el).getPropertyValue('display') != 'none';
    }

    function overlayObserver(mode) {
      return new Promise(function(resolve) {
        function listener() {
          element.removeEventListener('iron-overlay-' + mode, listener);
          resolve();
        }
        element.addEventListener('iron-overlay-' + mode, listener);
      });
    }

    function testConfirmationDialog(done, cc) {
      var yesButton =
          element.$$('.reviewerConfirmationButtons gr-button:first-child');
      var noButton =
          element.$$('.reviewerConfirmationButtons gr-button:last-child');

      element.serverConfig = {note_db_enabled: true};
      element._ccPendingConfirmation = null;
      element._reviewerPendingConfirmation = null;
      flushAsynchronousOperations();
      assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));

      // Cause the confirmation dialog to display.
      var observer = overlayObserver('opened');
      var group = {
        id: 'id',
        name: 'name',
      };
      if (cc) {
        element._ccPendingConfirmation = {
          group: group,
          count: 10,
        };
      } else {
        element._reviewerPendingConfirmation = {
          group: group,
          count: 10,
        };
      }
      flushAsynchronousOperations();

      if (cc) {
        assert.deepEqual(
            element._ccPendingConfirmation,
            element._pendingConfirmationDetails);
      } else {
        assert.deepEqual(
            element._reviewerPendingConfirmation,
            element._pendingConfirmationDetails);
      }

      observer.then(function() {
        assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay));
        observer = overlayObserver('closed');
        var expected = 'Group name has 10 members';
        assert.notEqual(
            element.$.reviewerConfirmationOverlay.innerText.indexOf(expected),
            -1);
        MockInteractions.tap(noButton); // close the overlay
        return observer;
      }).then(function() {
        assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));

        // We should be focused on account entry input.
        assert.equal(getActiveElement().id, 'input');

        // No reviewer/CC should have been added.
        assert.equal(element.$$('#ccs').additions().length, 0);
        assert.equal(element.$.reviewers.additions().length, 0);

        // Reopen confirmation dialog.
        observer = overlayObserver('opened');
        if (cc) {
          element._ccPendingConfirmation = {
            group: group,
            count: 10,
          };
        } else {
          element._reviewerPendingConfirmation = {
            group: group,
            count: 10,
          };
        }
        return observer;
      }).then(function() {
        assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay));
        observer = overlayObserver('closed');
        MockInteractions.tap(yesButton); // Confirm the group.
        return observer;
      }).then(function() {
        assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));
        var additions = cc ?
            element.$$('#ccs').additions() :
            element.$.reviewers.additions();
        assert.deepEqual(
            additions,
            [
              {
                group: {
                  id: 'id',
                  name: 'name',
                  confirmed: true,
                  _group: true,
                  _pendingAdd: true,
                },
              },
            ]);

        // We should be focused on account entry input.
        assert.equal(getActiveElement().id, 'input');
      }).then(done);
    };

    test('cc confirmation', function(done) {
      testConfirmationDialog(done, true);
    });

    test('reviewer confirmation', function(done) {
      testConfirmationDialog(done, false);
    });

    test('_getStorageLocation', function() {
      var actual = element._getStorageLocation();
      assert.equal(actual.changeNum, changeNum);
      assert.equal(actual.patchNum, patchNum);
      assert.equal(actual.path, '@change');
    });

    test('gets draft from storage on open', function() {
      var storedDraft = 'hello world';
      getDraftCommentStub.returns({message: storedDraft});
      element.open();
      assert.isTrue(getDraftCommentStub.called);
      assert.equal(element.draft, storedDraft);
    });

    test('blank if no stored draft', function() {
      getDraftCommentStub.returns(null);
      element.open();
      assert.isTrue(getDraftCommentStub.called);
      assert.equal(element.draft, '');
    });

    test('updates stored draft on edits', function() {
      var firstEdit = 'hello';
      var location = element._getStorageLocation();

      element.draft = firstEdit;
      element.flushDebouncer('store');

      assert.isTrue(setDraftCommentStub.calledWith(location, firstEdit));

      element.draft = '';
      element.flushDebouncer('store');

      assert.isTrue(eraseDraftCommentStub.calledWith(location));
    });

    test('400 converts to human-readable server-error', function(done) {
      sandbox.stub(window, 'fetch', function() {
        var text = '....{"reviewers":{"id1":{"error":"first error"}},' +
          '"ccs":{"id2":{"error":"second error"}}}';
        return Promise.resolve({
          ok: false,
          status: 400,
          text: function() { return Promise.resolve(text); },
        });
      });

      element.addEventListener('server-error', function(event) {
        if (event.target !== element) {
          return;
        }
        event.detail.response.text().then(function(body) {
          assert.equal(body, 'first error, second error');
        });
      });

      // Async tick is needed because iron-selector content is distributed and
      // distributed content requires an observer to be set up.
      flush(function() { element.send().then(done); });
    });

    test('ccs are displayed if NoteDb is enabled', function() {
      function hasCc() {
        flushAsynchronousOperations();
        return !!element.$$('#ccs');
      }

      element.serverConfig = {};
      assert.isFalse(hasCc());

      element.serverConfig = {note_db_enabled: true};
      assert.isTrue(hasCc());
    });

    test('filterReviewerSuggestion', function() {
      var owner = makeAccount();
      var reviewer1 = makeAccount();
      var reviewer2 = makeGroup();
      var cc1 = makeAccount();
      var cc2 = makeGroup();

      element._owner = owner;
      element._reviewers = [reviewer1, reviewer2];
      element._ccs = [cc1, cc2];

      assert.isTrue(
          element._filterReviewerSuggestion({account: makeAccount()}));
      assert.isTrue(element._filterReviewerSuggestion({group: makeGroup()}));

      // Owner should be excluded.
      assert.isFalse(element._filterReviewerSuggestion({account: owner}));

      // Existing and pending reviewers should be excluded.
      assert.isFalse(element._filterReviewerSuggestion({account: reviewer1}));
      assert.isFalse(element._filterReviewerSuggestion({group: reviewer2}));

      // Existing and pending CCs should be excluded.
      assert.isFalse(element._filterReviewerSuggestion({account: cc1}));
      assert.isFalse(element._filterReviewerSuggestion({group: cc2}));
    });

    test('_chooseFocusTarget', function() {
      element._account = null;
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.BODY);

      element._account = {_account_id: 1};
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.BODY);

      element.change.owner = {_account_id: 2};
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.BODY);

      element.change.owner._account_id = 1;
      element.change._reviewers = null;
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.REVIEWERS);

      element._reviewers = [];
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.REVIEWERS);

      element._reviewers.push({});
      assert.strictEqual(
          element._chooseFocusTarget(), element.FocusTarget.BODY);
    });

    test('only send labels that have changed', function(done) {
      flush(function() {
        var saveReviewStub = sinon.stub(element, '_saveReview',
            function(review) {
          assert.deepEqual(review.labels, {Verified: -1});
          return Promise.resolve({ok: true});
        });

        element.addEventListener('send', function() {
          saveReviewStub.restore();
          done();
        });
        // Without wrapping this test in flush(), the below two calls to
        // MockInteractions.tap() cause a race in some situations in shadow DOM.
        // The send button can be tapped before the others, causing the test to
        // fail.
        MockInteractions.tap(element.$$(
            'iron-selector[data-label="Verified"] > ' +
            'gr-button[data-value="-1"]'));
        MockInteractions.tap(element.$$('.send'));
      });
    });

    test('do not display tooltips on touch devices', function() {
      element._account = {_account_id: 1};
      element.set(['change', 'labels', 'Verified', 'all'],
          [{_account_id: 1, value: -1}]);
      element.labels = {
        Verified: {
          values: {
            '-1': 'Fails',
            ' 0': 'No score',
            '+1': 'Verified'
          },
          default_value: 0,
        },
        'Code-Review': {
          values: {
            '-2': 'Do not submit',
            '-1': 'I would prefer that you didn\'t submit this',
            ' 0': 'No score',
            '+1': 'Looks good to me, but someone else must approve',
            '+2': 'Looks good to me, approved'
          },
          default_value: 0,
        },
      };

      flushAsynchronousOperations();

      var verifiedBtn = element.$$(
          'iron-selector[data-label="Verified"] > ' +
          'gr-button[data-value="-1"]');

      // On touch devices, tooltips should not be shown.
      verifiedBtn._isTouchDevice = true;
      verifiedBtn._handleShowTooltip();
      assert.isNotOk(verifiedBtn._tooltip);
      verifiedBtn._handleHideTooltip();
      assert.isNotOk(verifiedBtn._tooltip);

      // On other devices, tooltips should be shown.
      verifiedBtn._isTouchDevice = false;
      verifiedBtn._handleShowTooltip();
      assert.isOk(verifiedBtn._tooltip);
      verifiedBtn._handleHideTooltip();
      assert.isNotOk(verifiedBtn._tooltip);
    });

    test('_processReviewerChange', function() {
      var mockIndexSplices = function(toRemove) {
        return [{
          removed: [toRemove],
        }];
      };

      element._processReviewerChange(
          mockIndexSplices(makeAccount()), 'REVIEWER');
      assert.equal(element._reviewersPendingRemove.REVIEWER.length, 1);
    });

    test('_purgeReviewersPendingRemove', function() {
      var removeStub = sandbox.stub(element, '_removeAccount');
      var mock = function() {
        element._reviewersPendingRemove = {
          test: [makeAccount()],
          test2: [makeAccount(), makeAccount()],
        };
      };
      var checkObjEmpty = function(obj) {
        for (var prop in obj) {
          if (obj.hasOwnProperty(prop) && obj[prop].length) { return false; }
        }
        return true;
      };
      mock();
      element._purgeReviewersPendingRemove(true); // Cancel
      assert.isFalse(removeStub.called);
      assert.isTrue(checkObjEmpty(element._reviewersPendingRemove));

      mock();
      element._purgeReviewersPendingRemove(false); // Submit
      assert.isTrue(removeStub.called);
      assert.isTrue(checkObjEmpty(element._reviewersPendingRemove));
    });

    test('_removeAccount', function(done) {
      sandbox.stub(element.$.restAPI, 'removeChangeReviewer')
          .returns(Promise.resolve({ok: true}));
      var arr = [makeAccount(), makeAccount()];
      element.change.reviewers = {
        REVIEWER: arr.slice(),
      };

      element._removeAccount(arr[1], 'REVIEWER').then(function() {
        assert.equal(element.change.reviewers.REVIEWER.length, 1);
        assert.deepEqual(element.change.reviewers.REVIEWER, arr.slice(0, 1));
        done();
      });
    });
  });
</script>
