<!--
@license
Copyright (C) 2016 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.
-->
<!-- Polymer included for the html import polyfill. -->
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<title>gr-patch-set-behavior</title>

<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>

<script type="module">
import '../../test/common-test-setup.js';
import './gr-patch-set-behavior.js';
suite('gr-patch-set-behavior tests', () => {
  test('getRevisionByPatchNum', () => {
    const get = Gerrit.PatchSetBehavior.getRevisionByPatchNum;
    const revisions = [
      {_number: 0},
      {_number: 1},
      {_number: 2},
    ];
    assert.deepEqual(get(revisions, '1'), revisions[1]);
    assert.deepEqual(get(revisions, 2), revisions[2]);
    assert.equal(get(revisions, '3'), undefined);
  });

  test('fetchChangeUpdates on latest', done => {
    const knownChange = {
      revisions: {
        sha1: {description: 'patch 1', _number: 1},
        sha2: {description: 'patch 2', _number: 2},
      },
      status: 'NEW',
      messages: [],
    };
    const mockRestApi = {
      getChangeDetail() {
        return Promise.resolve(knownChange);
      },
    };
    Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
        .then(result => {
          assert.isTrue(result.isLatest);
          assert.isNotOk(result.newStatus);
          assert.isFalse(result.newMessages);
          done();
        });
  });

  test('fetchChangeUpdates not on latest', done => {
    const knownChange = {
      revisions: {
        sha1: {description: 'patch 1', _number: 1},
        sha2: {description: 'patch 2', _number: 2},
      },
      status: 'NEW',
      messages: [],
    };
    const actualChange = {
      revisions: {
        sha1: {description: 'patch 1', _number: 1},
        sha2: {description: 'patch 2', _number: 2},
        sha3: {description: 'patch 3', _number: 3},
      },
      status: 'NEW',
      messages: [],
    };
    const mockRestApi = {
      getChangeDetail() {
        return Promise.resolve(actualChange);
      },
    };
    Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
        .then(result => {
          assert.isFalse(result.isLatest);
          assert.isNotOk(result.newStatus);
          assert.isFalse(result.newMessages);
          done();
        });
  });

  test('fetchChangeUpdates new status', done => {
    const knownChange = {
      revisions: {
        sha1: {description: 'patch 1', _number: 1},
        sha2: {description: 'patch 2', _number: 2},
      },
      status: 'NEW',
      messages: [],
    };
    const actualChange = {
      revisions: {
        sha1: {description: 'patch 1', _number: 1},
        sha2: {description: 'patch 2', _number: 2},
      },
      status: 'MERGED',
      messages: [],
    };
    const mockRestApi = {
      getChangeDetail() {
        return Promise.resolve(actualChange);
      },
    };
    Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
        .then(result => {
          assert.isTrue(result.isLatest);
          assert.equal(result.newStatus, 'MERGED');
          assert.isFalse(result.newMessages);
          done();
        });
  });

  test('fetchChangeUpdates new messages', done => {
    const knownChange = {
      revisions: {
        sha1: {description: 'patch 1', _number: 1},
        sha2: {description: 'patch 2', _number: 2},
      },
      status: 'NEW',
      messages: [],
    };
    const actualChange = {
      revisions: {
        sha1: {description: 'patch 1', _number: 1},
        sha2: {description: 'patch 2', _number: 2},
      },
      status: 'NEW',
      messages: [{message: 'blah blah'}],
    };
    const mockRestApi = {
      getChangeDetail() {
        return Promise.resolve(actualChange);
      },
    };
    Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
        .then(result => {
          assert.isTrue(result.isLatest);
          assert.isNotOk(result.newStatus);
          assert.isTrue(result.newMessages);
          done();
        });
  });

  test('_computeWipForPatchSets', () => {
    // Compute patch sets for a given timeline on a change. The initial WIP
    // property of the change can be true or false. The map of tags by
    // revision is keyed by patch set number. Each value is a list of change
    // message tags in the order that they occurred in the timeline. These
    // indicate actions that modify the WIP property of the change and/or
    // create new patch sets.
    //
    // Returns the actual results with an assertWip method that can be used
    // to compare against an expected value for a particular patch set.
    const compute = (initialWip, tagsByRevision) => {
      const change = {
        messages: [],
        work_in_progress: initialWip,
      };
      const revs = Object.keys(tagsByRevision).sort((a, b) => a - b);
      for (const rev of revs) {
        for (const tag of tagsByRevision[rev]) {
          change.messages.push({
            tag,
            _revision_number: rev,
          });
        }
      }
      let patchNums = revs.map(rev => { return {num: rev}; });
      patchNums = Gerrit.PatchSetBehavior._computeWipForPatchSets(
          change, patchNums);
      const actualWipsByRevision = {};
      for (const patchNum of patchNums) {
        actualWipsByRevision[patchNum.num] = patchNum.wip;
      }
      const verifier = {
        assertWip(revision, expectedWip) {
          const patchNum = patchNums.find(patchNum => patchNum.num == revision);
          if (!patchNum) {
            assert.fail('revision ' + revision + ' not found');
          }
          assert.equal(patchNum.wip, expectedWip,
              'wip state for ' + revision + ' is ' +
            patchNum.wip + '; expected ' + expectedWip);
          return verifier;
        },
      };
      return verifier;
    };

    compute(false, {1: ['upload']}).assertWip(1, false);
    compute(true, {1: ['upload']}).assertWip(1, true);

    const setWip = 'autogenerated:gerrit:setWorkInProgress';
    const uploadInWip = 'autogenerated:gerrit:newWipPatchSet';
    const clearWip = 'autogenerated:gerrit:setReadyForReview';

    compute(false, {
      1: ['upload', setWip],
      2: ['upload'],
      3: ['upload', clearWip],
      4: ['upload', setWip],
    }).assertWip(1, false) // Change was created with PS1 ready for review
        .assertWip(2, true) // PS2 was uploaded during WIP
        .assertWip(3, false) // PS3 was marked ready for review after upload
        .assertWip(4, false); // PS4 was uploaded ready for review

    compute(false, {
      1: [uploadInWip, null, 'addReviewer'],
      2: ['upload'],
      3: ['upload', clearWip, setWip],
      4: ['upload'],
      5: ['upload', clearWip],
      6: [uploadInWip],
    }).assertWip(1, true) // Change was created in WIP
        .assertWip(2, true) // PS2 was uploaded during WIP
        .assertWip(3, false) // PS3 was marked ready for review
        .assertWip(4, true) // PS4 was uploaded during WIP
        .assertWip(5, false) // PS5 was marked ready for review
        .assertWip(6, true); // PS6 was uploaded with WIP option
  });

  test('patchNumEquals', () => {
    const equals = Gerrit.PatchSetBehavior.patchNumEquals;
    assert.isFalse(equals('edit', 'PARENT'));
    assert.isFalse(equals('edit', NaN));
    assert.isFalse(equals(1, '2'));

    assert.isTrue(equals(1, '1'));
    assert.isTrue(equals(1, 1));
    assert.isTrue(equals('edit', 'edit'));
    assert.isTrue(equals('PARENT', 'PARENT'));
  });

  test('isMergeParent', () => {
    const isParent = Gerrit.PatchSetBehavior.isMergeParent;
    assert.isFalse(isParent(1));
    assert.isFalse(isParent(4321));
    assert.isFalse(isParent('52'));
    assert.isFalse(isParent('edit'));
    assert.isFalse(isParent('PARENT'));
    assert.isFalse(isParent(0));

    assert.isTrue(isParent(-23));
    assert.isTrue(isParent(-1));
    assert.isTrue(isParent('-42'));
  });

  test('findEditParentRevision', () => {
    const findParent = Gerrit.PatchSetBehavior.findEditParentRevision;
    let revisions = [
      {_number: 0},
      {_number: 1},
      {_number: 2},
    ];
    assert.strictEqual(findParent(revisions), null);

    revisions = [...revisions, {_number: 'edit', basePatchNum: 3}];
    assert.strictEqual(findParent(revisions), null);

    revisions = [...revisions, {_number: 3}];
    assert.deepEqual(findParent(revisions), {_number: 3});
  });

  test('findEditParentPatchNum', () => {
    const findNum = Gerrit.PatchSetBehavior.findEditParentPatchNum;
    let revisions = [
      {_number: 0},
      {_number: 1},
      {_number: 2},
    ];
    assert.equal(findNum(revisions), -1);

    revisions =
        [...revisions, {_number: 'edit', basePatchNum: 3}, {_number: 3}];
    assert.deepEqual(findNum(revisions), 3);
  });

  test('sortRevisions', () => {
    const sort = Gerrit.PatchSetBehavior.sortRevisions;
    const revisions = [
      {_number: 0},
      {_number: 2},
      {_number: 1},
    ];
    const sorted = [
      {_number: 2},
      {_number: 1},
      {_number: 0},
    ];

    assert.deepEqual(sort(revisions), sorted);

    // Edit patchset should follow directly after its basePatchNum.
    revisions.push({_number: 'edit', basePatchNum: 2});
    sorted.unshift({_number: 'edit', basePatchNum: 2});
    assert.deepEqual(sort(revisions), sorted);

    revisions[0].basePatchNum = 0;
    const edit = sorted.shift();
    edit.basePatchNum = 0;
    // Edit patchset should be at index 2.
    sorted.splice(2, 0, edit);
    assert.deepEqual(sort(revisions), sorted);
  });

  test('getParentIndex', () => {
    assert.equal(Gerrit.PatchSetBehavior.getParentIndex('-13'), 13);
    assert.equal(Gerrit.PatchSetBehavior.getParentIndex(-4), 4);
  });
});
</script>
