<!--
@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 {PatchSetBehavior} from './gr-patch-set-behavior.js';
suite('gr-patch-set-behavior tests', () => {
  test('getRevisionByPatchNum', () => {
    const get = 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);
      },
    };
    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);
      },
    };
    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);
      },
    };
    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);
      },
    };
    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 = 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 = 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 = 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 = 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 = 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 = 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(PatchSetBehavior.getParentIndex('-13'), 13);
    assert.equal(PatchSetBehavior.getParentIndex(-4), 4);
  });
});
</script>
