<!DOCTYPE html>
<!--
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.
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-storage</title>

<script src="../../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>

<link rel="import" href="gr-storage.html">

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

<script>
  suite('gr-storage tests', function() {
    var element;

    function mockStorage(opt_quotaExceeded) {
      return {
        getItem: function(key) { return this[key]; },
        removeItem: function(key) { delete this[key]; },
        setItem: function(key, value) {
          if (opt_quotaExceeded) { throw {code: 22}; /* Quota exceeded */ }
          this[key] = value;
        },
      };
    }

    setup(function() {
      element = fixture('basic');
      element._storage = mockStorage();
    });

    test('storing, retrieving and erasing drafts', function() {
      var changeNum = 1234;
      var patchNum = 5;
      var path = 'my_source_file.js';
      var line = 123;
      var location = {
        changeNum: changeNum,
        patchNum: patchNum,
        path: path,
        line: line,
      };

      // The key is in the expected format.
      var key = element._getDraftKey(location);
      assert.equal(key, ['draft', changeNum, patchNum, path, line].join(':'));

      // There should be no draft initially.
      var draft = element.getDraftComment(location);
      assert.isNotOk(draft);

      // Setting the draft stores it under the expected key.
      element.setDraftComment(location, 'my comment');
      assert.isOk(element._storage.getItem(key));
      assert.equal(JSON.parse(element._storage.getItem(key)).message,
          'my comment');
      assert.isOk(JSON.parse(element._storage.getItem(key)).updated);

      // Erasing the draft removes the key.
      element.eraseDraftComment(location);
      assert.isNotOk(element._storage.getItem(key));
    });

    test('automatically removes old drafts', function() {
      var changeNum = 1234;
      var patchNum = 5;
      var path = 'my_source_file.js';
      var line = 123;
      var location = {
        changeNum: changeNum,
        patchNum: patchNum,
        path: path,
        line: line,
      };

      var key = element._getDraftKey(location);

      // Make sure that the call to cleanup doesn't get throttled.
      element._lastCleanup = 0;

      var cleanupSpy = sinon.spy(element, '_cleanupDrafts');

      // Create a message with a timestamp that is a second behind the max age.
      element._storage.setItem(key, JSON.stringify({
        message: 'old message',
        updated: Date.now() - 24 * 60 * 60 * 1000 - 1000,
      }));

      // Getting the draft should cause it to be removed.
      var draft = element.getDraftComment(location);

      assert.isTrue(cleanupSpy.called);
      assert.isNotOk(draft);
      assert.isNotOk(element._storage.getItem(key));

      cleanupSpy.restore();
    });

    test('_getDraftKey', function() {
      var changeNum = 1234;
      var patchNum = 5;
      var path = 'my_source_file.js';
      var line = 123;
      var location = {
        changeNum: changeNum,
        patchNum: patchNum,
        path: path,
        line: line,
      };
      var expectedResult = 'draft:1234:5:my_source_file.js:123';
      assert.equal(element._getDraftKey(location), expectedResult);
      location.range = {
        start_character: 1,
        start_line: 1,
        end_character: 1,
        end_line: 2,
      };
      expectedResult = 'draft:1234:5:my_source_file.js:123:1-1-1-2';
      assert.equal(element._getDraftKey(location), expectedResult);
    });

    test('exceeded quota disables storage', function() {
      element._storage = mockStorage(true);
      assert.isFalse(element._exceededQuota);

      var changeNum = 1234;
      var patchNum = 5;
      var path = 'my_source_file.js';
      var line = 123;
      var location = {
        changeNum: changeNum,
        patchNum: patchNum,
        path: path,
        line: line,
      };
      var key = element._getDraftKey(location);
      element.setDraftComment(location, 'my comment');
      assert.isTrue(element._exceededQuota);
      assert.isNotOk(element._storage.getItem(key));
    });
  });
</script>
