<!DOCTYPE html>
<!--
@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-rule-editor</title>

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

<script src="/node_modules/page/page.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-rule-editor></gr-rule-editor>
  </template>
</test-fixture>

<script type="module">
import '../../../test/common-test-setup.js';
import './gr-rule-editor.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
suite('gr-rule-editor tests', () => {
  let element;
  let sandbox;

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

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

  suite('unit tests', () => {
    test('_computeForce, _computeForceClass, and _computeForceOptions',
        () => {
          const ForcePushOptions = {
            ALLOW: [
              {name: 'Allow pushing (but not force pushing)', value: false},
              {name: 'Allow pushing with or without force', value: true},
            ],
            BLOCK: [
              {name: 'Block pushing with or without force', value: false},
              {name: 'Block force pushing', value: true},
            ],
          };

          const FORCE_EDIT_OPTIONS = [
            {
              name: 'No Force Edit',
              value: false,
            },
            {
              name: 'Force Edit',
              value: true,
            },
          ];
          let permission = 'push';
          let action = 'ALLOW';
          assert.isTrue(element._computeForce(permission, action));
          assert.equal(element._computeForceClass(permission, action),
              'force');
          assert.deepEqual(element._computeForceOptions(permission, action),
              ForcePushOptions.ALLOW);

          action = 'BLOCK';
          assert.isTrue(element._computeForce(permission, action));
          assert.equal(element._computeForceClass(permission, action),
              'force');
          assert.deepEqual(element._computeForceOptions(permission, action),
              ForcePushOptions.BLOCK);

          action = 'DENY';
          assert.isFalse(element._computeForce(permission, action));
          assert.equal(element._computeForceClass(permission, action), '');
          assert.equal(
              element._computeForceOptions(permission, action).length, 0);

          permission = 'editTopicName';
          assert.isTrue(element._computeForce(permission));
          assert.equal(element._computeForceClass(permission), 'force');
          assert.deepEqual(element._computeForceOptions(permission),
              FORCE_EDIT_OPTIONS);
          permission = 'submit';
          assert.isFalse(element._computeForce(permission));
          assert.equal(element._computeForceClass(permission), '');
          assert.deepEqual(element._computeForceOptions(permission), []);
        });

    test('_computeSectionClass', () => {
      let deleted = true;
      let editing = false;
      assert.equal(element._computeSectionClass(editing, deleted), 'deleted');

      deleted = false;
      assert.equal(element._computeSectionClass(editing, deleted), '');

      editing = true;
      assert.equal(element._computeSectionClass(editing, deleted), 'editing');

      deleted = true;
      assert.equal(element._computeSectionClass(editing, deleted),
          'editing deleted');
    });

    test('_getDefaultRuleValues', () => {
      let permission = 'priority';
      let label;
      assert.deepEqual(element._getDefaultRuleValues(permission, label),
          {action: 'BATCH'});
      permission = 'label-Code-Review';
      label = {values: [
        {value: -2, text: 'This shall not be merged'},
        {value: -1, text: 'I would prefer this is not merged as is'},
        {value: -0, text: 'No score'},
        {value: 1, text: 'Looks good to me, but someone else must approve'},
        {value: 2, text: 'Looks good to me, approved'},
      ]};
      assert.deepEqual(element._getDefaultRuleValues(permission, label),
          {action: 'ALLOW', max: 2, min: -2});
      permission = 'push';
      label = undefined;
      assert.deepEqual(element._getDefaultRuleValues(permission, label),
          {action: 'ALLOW', force: false});
      permission = 'submit';
      assert.deepEqual(element._getDefaultRuleValues(permission, label),
          {action: 'ALLOW'});
    });

    test('_setDefaultRuleValues', () => {
      element.rule = {id: 123};
      const defaultValue = {action: 'ALLOW'};
      sandbox.stub(element, '_getDefaultRuleValues').returns(defaultValue);
      element._setDefaultRuleValues();
      assert.isTrue(element._getDefaultRuleValues.called);
      assert.equal(element.rule.value, defaultValue);
    });

    test('_computeOptions', () => {
      const PRIORITY_OPTIONS = [
        'BATCH',
        'INTERACTIVE',
      ];
      const DROPDOWN_OPTIONS = [
        'ALLOW',
        'DENY',
        'BLOCK',
      ];
      let permission = 'priority';
      assert.deepEqual(element._computeOptions(permission), PRIORITY_OPTIONS);
      permission = 'submit';
      assert.deepEqual(element._computeOptions(permission), DROPDOWN_OPTIONS);
    });

    test('_handleValueChange', () => {
      const modifiedHandler = sandbox.stub();
      element.rule = {value: {}};
      element.addEventListener('access-modified', modifiedHandler);
      element._handleValueChange();
      assert.isNotOk(element.rule.value.modified);
      element._originalRuleValues = {};
      element._handleValueChange();
      assert.isTrue(element.rule.value.modified);
      assert.isTrue(modifiedHandler.called);
    });

    test('_handleAccessSaved', () => {
      const originalValue = {action: 'DENY'};
      const newValue = {action: 'ALLOW'};
      element._originalRuleValues = originalValue;
      element.rule = {value: newValue};
      element._handleAccessSaved();
      assert.deepEqual(element._originalRuleValues, newValue);
    });

    test('_setOriginalRuleValues', () => {
      const value = {
        action: 'ALLOW',
        force: false,
      };
      element._setOriginalRuleValues(value);
      assert.deepEqual(element._originalRuleValues, value);
    });
  });

  suite('already existing generic rule', () => {
    setup(done => {
      element.group = 'Group Name';
      element.permission = 'submit';
      element.rule = {
        id: '123',
        value: {
          action: 'ALLOW',
          force: false,
        },
      };
      element.section = 'refs/*';

      // Typically called on ready since elements will have properies defined
      // by the parent element.
      element._setupValues(element.rule);
      flushAsynchronousOperations();
      flush(() => {
        element.attached();
        done();
      });
    });

    test('_ruleValues and _originalRuleValues are set correctly', () => {
      assert.deepEqual(element._originalRuleValues, element.rule.value);
    });

    test('values are set correctly', () => {
      assert.equal(element.$.action.bindValue, element.rule.value.action);
      assert.isNotOk(dom(element.root).querySelector('#labelMin'));
      assert.isNotOk(dom(element.root).querySelector('#labelMax'));
      assert.isFalse(element.$.force.classList.contains('force'));
    });

    test('modify and cancel restores original values', () => {
      element.editing = true;
      assert.notEqual(getComputedStyle(element.$.removeBtn).display, 'none');
      assert.isNotOk(element.rule.value.modified);
      element.$.action.bindValue = 'DENY';
      assert.isTrue(element.rule.value.modified);
      element.editing = false;
      assert.equal(getComputedStyle(element.$.removeBtn).display, 'none');
      assert.deepEqual(element._originalRuleValues, element.rule.value);
      assert.equal(element.$.action.bindValue, 'ALLOW');
      assert.isNotOk(element.rule.value.modified);
    });

    test('modify value', () => {
      assert.isNotOk(element.rule.value.modified);
      element.$.action.bindValue = 'DENY';
      flushAsynchronousOperations();
      assert.isTrue(element.rule.value.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element._originalRuleValues, element.rule.value);
    });

    test('all selects are disabled when not in edit mode', () => {
      const selects = dom(element.root).querySelectorAll('select');
      for (const select of selects) {
        assert.isTrue(select.disabled);
      }
      element.editing = true;
      for (const select of selects) {
        assert.isFalse(select.disabled);
      }
    });

    test('remove rule and undo remove', () => {
      element.editing = true;
      element.rule = {id: 123, value: {action: 'ALLOW'}};
      assert.isFalse(
          element.$.deletedContainer.classList.contains('deleted'));
      MockInteractions.tap(element.$.removeBtn);
      assert.isTrue(element.$.deletedContainer.classList.contains('deleted'));
      assert.isTrue(element._deleted);
      assert.isTrue(element.rule.value.deleted);

      MockInteractions.tap(element.$.undoRemoveBtn);
      assert.isFalse(element._deleted);
      assert.isNotOk(element.rule.value.deleted);
    });

    test('remove rule and cancel', () => {
      element.editing = true;
      assert.notEqual(getComputedStyle(element.$.removeBtn).display, 'none');
      assert.equal(getComputedStyle(element.$.deletedContainer).display,
          'none');

      element.rule = {id: 123, value: {action: 'ALLOW'}};
      MockInteractions.tap(element.$.removeBtn);
      assert.notEqual(getComputedStyle(element.$.removeBtn).display, 'none');
      assert.notEqual(getComputedStyle(element.$.deletedContainer).display,
          'none');
      assert.isTrue(element._deleted);
      assert.isTrue(element.rule.value.deleted);

      element.editing = false;
      assert.isFalse(element._deleted);
      assert.isNotOk(element.rule.value.deleted);
      assert.isNotOk(element.rule.value.modified);

      assert.deepEqual(element._originalRuleValues, element.rule.value);
      assert.equal(getComputedStyle(element.$.removeBtn).display, 'none');
      assert.equal(getComputedStyle(element.$.deletedContainer).display,
          'none');
    });

    test('_computeGroupPath', () => {
      const group = '123';
      assert.equal(element._computeGroupPath(group),
          `/admin/groups/123`);
    });
  });

  suite('new edit rule', () => {
    setup(done => {
      element.group = 'Group Name';
      element.permission = 'editTopicName';
      element.rule = {
        id: '123',
      };
      element.section = 'refs/*';
      element._setupValues(element.rule);
      flushAsynchronousOperations();
      element.rule.value.added = true;
      flush(() => {
        element.attached();
        done();
      });
    });

    test('_ruleValues and _originalRuleValues are set correctly', () => {
      // Since the element does not already have default values, they should
      // be set. The original values should be set to those too.
      assert.isNotOk(element.rule.value.modified);
      const expectedRuleValue = {
        action: 'ALLOW',
        force: false,
        added: true,
      };
      assert.deepEqual(element.rule.value, expectedRuleValue);
      test('values are set correctly', () => {
        assert.equal(element.$.action.bindValue, expectedRuleValue.action);
        assert.equal(element.$.force.bindValue, expectedRuleValue.action);
      });
    });

    test('modify value', () => {
      assert.isNotOk(element.rule.value.modified);
      element.$.force.bindValue = true;
      flushAsynchronousOperations();
      assert.isTrue(element.rule.value.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element._originalRuleValues, element.rule.value);
    });

    test('remove value', () => {
      element.editing = true;
      const removeStub = sandbox.stub();
      element.addEventListener('added-rule-removed', removeStub);
      MockInteractions.tap(element.$.removeBtn);
      flushAsynchronousOperations();
      assert.isTrue(removeStub.called);
    });
  });

  suite('already existing rule with labels', () => {
    setup(done => {
      element.label = {values: [
        {value: -2, text: 'This shall not be merged'},
        {value: -1, text: 'I would prefer this is not merged as is'},
        {value: -0, text: 'No score'},
        {value: 1, text: 'Looks good to me, but someone else must approve'},
        {value: 2, text: 'Looks good to me, approved'},
      ]};
      element.group = 'Group Name';
      element.permission = 'label-Code-Review';
      element.rule = {
        id: '123',
        value: {
          action: 'ALLOW',
          force: false,
          max: 2,
          min: -2,
        },
      };
      element.section = 'refs/*';
      element._setupValues(element.rule);
      flushAsynchronousOperations();
      flush(() => {
        element.attached();
        done();
      });
    });

    test('_ruleValues and _originalRuleValues are set correctly', () => {
      assert.deepEqual(element._originalRuleValues, element.rule.value);
    });

    test('values are set correctly', () => {
      assert.equal(element.$.action.bindValue, element.rule.value.action);
      assert.equal(
          dom(element.root).querySelector('#labelMin').bindValue,
          element.rule.value.min);
      assert.equal(
          dom(element.root).querySelector('#labelMax').bindValue,
          element.rule.value.max);
      assert.isFalse(element.$.force.classList.contains('force'));
    });

    test('modify value', () => {
      const removeStub = sandbox.stub();
      element.addEventListener('added-rule-removed', removeStub);
      assert.isNotOk(element.rule.value.modified);
      dom(element.root).querySelector('#labelMin').bindValue = 1;
      flushAsynchronousOperations();
      assert.isTrue(element.rule.value.modified);
      assert.isFalse(removeStub.called);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element._originalRuleValues, element.rule.value);
    });
  });

  suite('new rule with labels', () => {
    setup(done => {
      sandbox.spy(element, '_setDefaultRuleValues');
      element.label = {values: [
        {value: -2, text: 'This shall not be merged'},
        {value: -1, text: 'I would prefer this is not merged as is'},
        {value: -0, text: 'No score'},
        {value: 1, text: 'Looks good to me, but someone else must approve'},
        {value: 2, text: 'Looks good to me, approved'},
      ]};
      element.group = 'Group Name';
      element.permission = 'label-Code-Review';
      element.rule = {
        id: '123',
      };
      element.section = 'refs/*';
      element._setupValues(element.rule);
      flushAsynchronousOperations();
      element.rule.value.added = true;
      flush(() => {
        element.attached();
        done();
      });
    });

    test('_ruleValues and _originalRuleValues are set correctly', () => {
      // Since the element does not already have default values, they should
      // be set. The original values should be set to those too.
      assert.isNotOk(element.rule.value.modified);
      assert.isTrue(element._setDefaultRuleValues.called);

      const expectedRuleValue = {
        max: element.label.values[element.label.values.length - 1].value,
        min: element.label.values[0].value,
        action: 'ALLOW',
        added: true,
      };
      assert.deepEqual(element.rule.value, expectedRuleValue);
      test('values are set correctly', () => {
        assert.equal(
            element.$.action.bindValue,
            expectedRuleValue.action);
        assert.equal(
            dom(element.root).querySelector('#labelMin').bindValue,
            expectedRuleValue.min);
        assert.equal(
            dom(element.root).querySelector('#labelMax').bindValue,
            expectedRuleValue.max);
      });
    });

    test('modify value', () => {
      assert.isNotOk(element.rule.value.modified);
      dom(element.root).querySelector('#labelMin').bindValue = 1;
      flushAsynchronousOperations();
      assert.isTrue(element.rule.value.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element._originalRuleValues, element.rule.value);
    });
  });

  suite('already existing push rule', () => {
    setup(done => {
      element.group = 'Group Name';
      element.permission = 'push';
      element.rule = {
        id: '123',
        value: {
          action: 'ALLOW',
          force: true,
        },
      };
      element.section = 'refs/*';
      element._setupValues(element.rule);
      flushAsynchronousOperations();
      flush(() => {
        element.attached();
        done();
      });
    });

    test('_ruleValues and _originalRuleValues are set correctly', () => {
      assert.deepEqual(element._originalRuleValues, element.rule.value);
    });

    test('values are set correctly', () => {
      assert.isTrue(element.$.force.classList.contains('force'));
      assert.equal(element.$.action.bindValue, element.rule.value.action);
      assert.equal(
          dom(element.root).querySelector('#force').bindValue,
          element.rule.value.force);
      assert.isNotOk(dom(element.root).querySelector('#labelMin'));
      assert.isNotOk(dom(element.root).querySelector('#labelMax'));
    });

    test('modify value', () => {
      assert.isNotOk(element.rule.value.modified);
      element.$.action.bindValue = false;
      flushAsynchronousOperations();
      assert.isTrue(element.rule.value.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element._originalRuleValues, element.rule.value);
    });
  });

  suite('new push rule', () => {
    setup(done => {
      element.group = 'Group Name';
      element.permission = 'push';
      element.rule = {
        id: '123',
      };
      element.section = 'refs/*';
      element._setupValues(element.rule);
      flushAsynchronousOperations();
      element.rule.value.added = true;
      flush(() => {
        element.attached();
        done();
      });
    });

    test('_ruleValues and _originalRuleValues are set correctly', () => {
      // Since the element does not already have default values, they should
      // be set. The original values should be set to those too.
      assert.isNotOk(element.rule.value.modified);
      const expectedRuleValue = {
        action: 'ALLOW',
        force: false,
        added: true,
      };
      assert.deepEqual(element.rule.value, expectedRuleValue);
      test('values are set correctly', () => {
        assert.equal(element.$.action.bindValue, expectedRuleValue.action);
        assert.equal(element.$.force.bindValue, expectedRuleValue.action);
      });
    });

    test('modify value', () => {
      assert.isNotOk(element.rule.value.modified);
      element.$.force.bindValue = true;
      flushAsynchronousOperations();
      assert.isTrue(element.rule.value.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element._originalRuleValues, element.rule.value);
    });
  });

  suite('already existing edit rule', () => {
    setup(done => {
      element.group = 'Group Name';
      element.permission = 'editTopicName';
      element.rule = {
        id: '123',
        value: {
          action: 'ALLOW',
          force: true,
        },
      };
      element.section = 'refs/*';
      element._setupValues(element.rule);
      flushAsynchronousOperations();
      flush(() => {
        element.attached();
        done();
      });
    });

    test('_ruleValues and _originalRuleValues are set correctly', () => {
      assert.deepEqual(element._originalRuleValues, element.rule.value);
    });

    test('values are set correctly', () => {
      assert.isTrue(element.$.force.classList.contains('force'));
      assert.equal(element.$.action.bindValue, element.rule.value.action);
      assert.equal(
          dom(element.root).querySelector('#force').bindValue,
          element.rule.value.force);
      assert.isNotOk(dom(element.root).querySelector('#labelMin'));
      assert.isNotOk(dom(element.root).querySelector('#labelMax'));
    });

    test('modify value', () => {
      assert.isNotOk(element.rule.value.modified);
      element.$.action.bindValue = false;
      flushAsynchronousOperations();
      assert.isTrue(element.rule.value.modified);

      // The original value should now differ from the rule values.
      assert.notDeepEqual(element._originalRuleValues, element.rule.value);
    });
  });
});
</script>
