<!DOCTYPE html>
<!--
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">
<title>gr-comment-api</title>

<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>

<link rel="import" href="./gr-comment-api.html">

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

<test-fixture id="basic">
  <template>
    <gr-comment-api></gr-comment-api>
  </template>
</test-fixture>

<script>
  suite('gr-comment-api tests', () => {
    const PARENT = 'PARENT';

    let element;
    let sandbox;

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

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

    test('loads logged-out', () => {
      const changeNum = 1234;

      sandbox.stub(element.$.restAPI, 'getLoggedIn')
          .returns(Promise.resolve(false));
      sandbox.stub(element.$.restAPI, 'getDiffComments')
          .returns(Promise.resolve({
            'foo.c': [{id: '123', message: 'foo bar', in_reply_to: '321'}],
          }));
      sandbox.stub(element.$.restAPI, 'getDiffRobotComments')
          .returns(Promise.resolve({'foo.c': [{id: '321', message: 'done'}]}));
      sandbox.stub(element.$.restAPI, 'getDiffDrafts')
          .returns(Promise.resolve({}));

      return element.loadAll(changeNum).then(() => {
        assert.isTrue(element.$.restAPI.getDiffComments.calledWithExactly(
            changeNum));
        assert.isTrue(element.$.restAPI.getDiffRobotComments.calledWithExactly(
            changeNum));
        assert.isTrue(element.$.restAPI.getDiffDrafts.calledWithExactly(
            changeNum));
        assert.isOk(element._changeComments._comments);
        assert.isOk(element._changeComments._robotComments);
        assert.deepEqual(element._changeComments._drafts, {});
      });
    });

    test('loads logged-in', () => {
      const changeNum = 1234;

      sandbox.stub(element.$.restAPI, 'getLoggedIn')
          .returns(Promise.resolve(true));
      sandbox.stub(element.$.restAPI, 'getDiffComments')
          .returns(Promise.resolve({
            'foo.c': [{id: '123', message: 'foo bar', in_reply_to: '321'}],
          }));
      sandbox.stub(element.$.restAPI, 'getDiffRobotComments')
          .returns(Promise.resolve({'foo.c': [{id: '321', message: 'done'}]}));
      sandbox.stub(element.$.restAPI, 'getDiffDrafts')
          .returns(Promise.resolve({'foo.c': [{id: '555', message: 'ack'}]}));

      return element.loadAll(changeNum).then(() => {
        assert.isTrue(element.$.restAPI.getDiffComments.calledWithExactly(
            changeNum));
        assert.isTrue(element.$.restAPI.getDiffRobotComments.calledWithExactly(
            changeNum));
        assert.isTrue(element.$.restAPI.getDiffDrafts.calledWithExactly(
            changeNum));
        assert.isOk(element._changeComments._comments);
        assert.isOk(element._changeComments._robotComments);
        assert.notDeepEqual(element._changeComments._drafts, {});
      });
    });

    suite('reloadDrafts', () => {
      let commentStub;
      let robotCommentStub;
      let draftStub;
      setup(() => {
        commentStub = sandbox.stub(element.$.restAPI, 'getDiffComments')
          .returns(Promise.resolve({}));
        robotCommentStub = sandbox.stub(element.$.restAPI,
            'getDiffRobotComments').returns(Promise.resolve({}));
        draftStub = sandbox.stub(element.$.restAPI, 'getDiffDrafts')
            .returns(Promise.resolve({}));
      });

      test('without loadAll first', done => {
        assert.isNotOk(element._changeComments);
        sandbox.spy(element, 'loadAll');
        element.reloadDrafts().then(() => {
          assert.isTrue(element.loadAll.called);
          assert.isOk(element._changeComments);
          assert.equal(commentStub.callCount, 1);
          assert.equal(robotCommentStub.callCount, 1);
          assert.equal(draftStub.callCount, 1);
          done();
        });
      });

      test('with loadAll first', done => {
        assert.isNotOk(element._changeComments);
        element.loadAll().then(() => {
          assert.isOk(element._changeComments);
          assert.equal(commentStub.callCount, 1);
          assert.equal(robotCommentStub.callCount, 1);
          assert.equal(draftStub.callCount, 1);
          return element.reloadDrafts();
        }).then(() => {
          assert.isOk(element._changeComments);
          assert.equal(commentStub.callCount, 1);
          assert.equal(robotCommentStub.callCount, 1);
          assert.equal(draftStub.callCount, 2);
          done();
        });
      });
    });

    suite('_changeComment methods', () => {
      setup(done => {
        const changeNum = 1234;
        stub('gr-rest-api-interface', {
          getDiffComments() { return Promise.resolve({}); },
          getDiffRobotComments() { return Promise.resolve({}); },
          getDiffDrafts() { return Promise.resolve({}); },
        });
        element.loadAll(changeNum).then(() => {
          done();
        });
      });

      test('_isInBaseOfPatchRange', () => {
        const comment = {patch_set: 1};
        const patchRange = {basePatchNum: 1, patchNum: 2};
        assert.isTrue(element._changeComments._isInBaseOfPatchRange(comment,
            patchRange));

        patchRange.basePatchNum = PARENT;
        assert.isFalse(element._changeComments._isInBaseOfPatchRange(comment,
            patchRange));

        comment.side = PARENT;
        assert.isFalse(element._changeComments._isInBaseOfPatchRange(comment,
            patchRange));

        comment.patch_set = 2;
        assert.isTrue(element._changeComments._isInBaseOfPatchRange(comment,
            patchRange));

        patchRange.basePatchNum = -2;
        comment.side = PARENT;
        comment.parent = 1;
        assert.isFalse(element._changeComments._isInBaseOfPatchRange(comment,
            patchRange));

        comment.parent = 2;
        assert.isTrue(element._changeComments._isInBaseOfPatchRange(comment,
            patchRange));
      });

      test('_isInRevisionOfPatchRange', () => {
        const comment = {patch_set: 123};
        const patchRange = {basePatchNum: 122, patchNum: 124};
        assert.isFalse(element._changeComments._isInRevisionOfPatchRange(
            comment, patchRange));

        patchRange.patchNum = 123;
        assert.isTrue(element._changeComments._isInRevisionOfPatchRange(
            comment, patchRange));

        comment.side = PARENT;
        assert.isFalse(element._changeComments._isInRevisionOfPatchRange(
            comment, patchRange));
      });

      test('_isInPatchRange', () => {
        const patchRange1 = {basePatchNum: 122, patchNum: 124};
        const patchRange2 = {basePatchNum: 123, patchNum: 125};
        const patchRange3 = {basePatchNum: 124, patchNum: 125};

        const isInBasePatchStub = sandbox.stub(element._changeComments,
            '_isInBaseOfPatchRange');
        const isInRevisionPatchStub = sandbox.stub(element._changeComments,
            '_isInRevisionOfPatchRange');

        isInBasePatchStub.withArgs({}, patchRange1).returns(true);
        isInBasePatchStub.withArgs({}, patchRange2).returns(false);
        isInBasePatchStub.withArgs({}, patchRange3).returns(false);

        isInRevisionPatchStub.withArgs({}, patchRange1).returns(false);
        isInRevisionPatchStub.withArgs({}, patchRange2).returns(true);
        isInRevisionPatchStub.withArgs({}, patchRange3).returns(false);

        assert.isTrue(element._changeComments._isInPatchRange({}, patchRange1));
        assert.isTrue(element._changeComments._isInPatchRange({}, patchRange2));
        assert.isFalse(element._changeComments._isInPatchRange({},
            patchRange3));
      });

      suite('comment ranges and paths', () => {
        setup(() => {
          element._changeComments._drafts = {
            'file/one': [
              {id: 11, patch_set: 2, side: PARENT},
              {id: 12, patch_set: 2},
            ],
          };
          element._changeComments._robotComments = {
            'file/one': [
              {id: 1, patch_set: 2, side: PARENT},
              {id: 2, patch_set: 2, unresolved: true},
            ],
          };
          element._changeComments._comments = {
            'file/one': [
              {id: 3, patch_set: 2, side: PARENT},
              {id: 4, patch_set: 2},
            ],
            'file/two': [
              {id: 5, patch_set: 2},
              {id: 6, patch_set: 3},
            ],
            'file/three': [
              {id: 7, patch_set: 2, side: PARENT, unresolved: true},
              {id: 8, patch_set: 3},
            ],
            'file/four': [
              {id: 9, patch_set: 5, side: PARENT},
              {i: 10, patch_set: 5},
            ],
          };
        });

        test('getPaths', () => {
          const patchRange = {basePatchNum: 1, patchNum: 4};
          let paths = element._changeComments.getPaths(patchRange);
          assert.equal(Object.keys(paths).length, 0);

          patchRange.basePatchNum = PARENT;
          patchRange.patchNum = 3;
          paths = element._changeComments.getPaths(patchRange);
          assert.notProperty(paths, 'file/one');
          assert.property(paths, 'file/two');
          assert.property(paths, 'file/three');
          assert.notProperty(paths, 'file/four');

          patchRange.patchNum = 2;
          paths = element._changeComments.getPaths(patchRange);
          assert.property(paths, 'file/one');
          assert.property(paths, 'file/two');
          assert.property(paths, 'file/three');
          assert.notProperty(paths, 'file/four');

          paths = element._changeComments.getPaths();
          assert.property(paths, 'file/one');
          assert.property(paths, 'file/two');
          assert.property(paths, 'file/three');
          assert.property(paths, 'file/four');
        });

        test('getCommentsBySideForPath', () => {
          const patchRange = {basePatchNum: 1, patchNum: 3};
          let path = 'file/one';
          let comments = element._changeComments.getCommentsBySideForPath(path,
              patchRange);
          assert.equal(comments.meta.changeNum, 1234);
          assert.equal(comments.left.length, 0);
          assert.equal(comments.right.length, 0);

          path = 'file/two';
          comments = element._changeComments.getCommentsBySideForPath(path,
              patchRange);
          assert.equal(comments.left.length, 0);
          assert.equal(comments.right.length, 1);

          patchRange.basePatchNum = 2;
          comments = element._changeComments.getCommentsBySideForPath(path,
              patchRange);
          assert.equal(comments.left.length, 1);
          assert.equal(comments.right.length, 1);

          patchRange.basePatchNum = PARENT;
          path = 'file/three';
          comments = element._changeComments.getCommentsBySideForPath(path,
              patchRange);
          assert.equal(comments.left.length, 0);
          assert.equal(comments.right.length, 1);
        });

        test('getAllCommentsForPath', () => {
          let path = 'file/one';
          let comments = element._changeComments.getAllCommentsForPath(path);
          assert.deepEqual(comments.length, 4);
          path = 'file/two';
          comments = element._changeComments.getAllCommentsForPath(path, 2);
          assert.deepEqual(comments.length, 1);
        });

        test('getAllDraftsForPath', () => {
          const path = 'file/one';
          const drafts = element._changeComments.getAllDraftsForPath(path);
          assert.deepEqual(drafts.length, 2);
        });

        test('computeUnresolvedNum', () => {
          assert.equal(element._changeComments
              .computeUnresolvedNum(2, 'file/one'), 1);
          assert.equal(element._changeComments
              .computeUnresolvedNum(1, 'file/one'), 0);
          assert.equal(element._changeComments
              .computeUnresolvedNum(2, 'file/three'), 1);
        });

        test('computeCommentCount', () => {
          assert.equal(element._changeComments
              .computeCommentCount(2, 'file/one'), 4);
          assert.equal(element._changeComments
              .computeCommentCount(1, 'file/one'), 0);
          assert.equal(element._changeComments
              .computeCommentCount(2, 'file/three'), 1);
        });

        test('computeDraftCount', () => {
          assert.equal(element._changeComments
              .computeDraftCount(2, 'file/one'), 2);
          assert.equal(element._changeComments
              .computeDraftCount(1, 'file/one'), 0);
          assert.equal(element._changeComments
              .computeDraftCount(2, 'file/three'), 0);
        });

        test('getAllPublishedComments', () => {
          const publishedComments = element._changeComments
              .getAllPublishedComments();
          assert.equal(Object.keys(publishedComments).length, 4);
          assert.equal(Object.keys(publishedComments[['file/one']]).length, 4);
        });
      });
    });
  });
</script>
